mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(templating): progress on template system rewrite #6048
This commit is contained in:
parent
7e8b279895
commit
46ebae7304
@ -10,7 +10,7 @@ function($, _, moment) {
|
|||||||
kbn.valueFormats = {};
|
kbn.valueFormats = {};
|
||||||
|
|
||||||
kbn.regexEscape = function(value) {
|
kbn.regexEscape = function(value) {
|
||||||
return value.replace(/[\\^$*+?.()|[\]{}]/g, '\\\\$&');
|
return value.replace(/[\\^$*+?.()|[\]{}\/]/g, '\\$&')
|
||||||
};
|
};
|
||||||
|
|
||||||
///// HELPER FUNCTIONS /////
|
///// HELPER FUNCTIONS /////
|
||||||
|
@ -5,9 +5,13 @@ import './editorCtrl';
|
|||||||
import {VariableSrv} from './variable_srv';
|
import {VariableSrv} from './variable_srv';
|
||||||
import {IntervalVariable} from './interval_variable';
|
import {IntervalVariable} from './interval_variable';
|
||||||
import {QueryVariable} from './query_variable';
|
import {QueryVariable} from './query_variable';
|
||||||
|
import {DatasourceVariable} from './datasource_variable';
|
||||||
|
import {CustomVariable} from './custom_variable';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
VariableSrv,
|
VariableSrv,
|
||||||
IntervalVariable,
|
IntervalVariable,
|
||||||
QueryVariable,
|
QueryVariable,
|
||||||
|
DatasourceVariable,
|
||||||
|
CustomVariable,
|
||||||
}
|
}
|
||||||
|
41
public/app/features/templating/custom_variable.ts
Normal file
41
public/app/features/templating/custom_variable.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import kbn from 'app/core/utils/kbn';
|
||||||
|
import {Variable} from './variable';
|
||||||
|
import {VariableSrv, variableConstructorMap} from './variable_srv';
|
||||||
|
|
||||||
|
export class CustomVariable implements Variable {
|
||||||
|
query: string;
|
||||||
|
options: any;
|
||||||
|
includeAll: boolean;
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(private model, private timeSrv, private templateSrv) {
|
||||||
|
_.extend(this, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(option) {
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOptions() {
|
||||||
|
// extract options in comma separated string
|
||||||
|
this.options = _.map(this.query.split(/[,]+/), function(text) {
|
||||||
|
return { text: text.trim(), value: text.trim() };
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.includeAll) {
|
||||||
|
this.addAllOption();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addAllOption() {
|
||||||
|
this.options.unshift({text: 'All', value: "$__all"});
|
||||||
|
}
|
||||||
|
|
||||||
|
dependsOn(variableName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variableConstructorMap['custom'] = CustomVariable;
|
56
public/app/features/templating/datasource_variable.ts
Normal file
56
public/app/features/templating/datasource_variable.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import kbn from 'app/core/utils/kbn';
|
||||||
|
import {Variable} from './variable';
|
||||||
|
import {VariableSrv, variableConstructorMap} from './variable_srv';
|
||||||
|
|
||||||
|
export class DatasourceVariable implements Variable {
|
||||||
|
regex: any;
|
||||||
|
query: string;
|
||||||
|
options: any;
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
constructor(private model, private datasourceSrv) {
|
||||||
|
_.extend(this, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(option) {
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOptions() {
|
||||||
|
var options = [];
|
||||||
|
var sources = this.datasourceSrv.getMetricSources({skipVariables: true});
|
||||||
|
var regex;
|
||||||
|
|
||||||
|
if (this.regex) {
|
||||||
|
regex = kbn.stringToJsRegex(this.regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < sources.length; i++) {
|
||||||
|
var source = sources[i];
|
||||||
|
// must match on type
|
||||||
|
if (source.meta.id !== this.query) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regex && !regex.exec(source.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push({text: source.name, value: source.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.length === 0) {
|
||||||
|
options.push({text: 'No data sources found', value: ''});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
dependsOn(variableName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variableConstructorMap['datasource'] = DatasourceVariable;
|
@ -43,6 +43,10 @@ export class IntervalVariable implements Variable {
|
|||||||
this.updateAutoValue();
|
this.updateAutoValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependsOn(variableName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variableConstructorMap['interval'] = IntervalVariable;
|
variableConstructorMap['interval'] = IntervalVariable;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
import {Variable} from './variable';
|
import {Variable, containsVariable} from './variable';
|
||||||
import {VariableSrv, variableConstructorMap} from './variable_srv';
|
import {VariableSrv, variableConstructorMap} from './variable_srv';
|
||||||
|
|
||||||
function getNoneOption() {
|
function getNoneOption() {
|
||||||
@ -17,8 +17,9 @@ export class QueryVariable implements Variable {
|
|||||||
options: any;
|
options: any;
|
||||||
current: any;
|
current: any;
|
||||||
includeAll: boolean;
|
includeAll: boolean;
|
||||||
|
refresh: number;
|
||||||
|
|
||||||
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv) {
|
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private $q) {
|
||||||
_.extend(this, model);
|
_.extend(this, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +34,23 @@ export class QueryVariable implements Variable {
|
|||||||
return this.variableSrv.variableUpdated(this);
|
return this.variableSrv.variableUpdated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setValueFromUrl(urlValue) {
|
||||||
|
var promise = this.$q.when();
|
||||||
|
|
||||||
|
if (this.refresh) {
|
||||||
|
promise = this.updateOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise.then(() => {
|
||||||
|
var option = _.find(this.options, op => {
|
||||||
|
return op.text === urlValue || op.value === urlValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
option = option || { text: urlValue, value: urlValue };
|
||||||
|
return this.setValue(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateOptions() {
|
updateOptions() {
|
||||||
return this.datasourceSrv.get(this.datasource)
|
return this.datasourceSrv.get(this.datasource)
|
||||||
.then(this.updateOptionsFromMetricFindQuery.bind(this))
|
.then(this.updateOptionsFromMetricFindQuery.bind(this))
|
||||||
@ -102,24 +120,30 @@ export class QueryVariable implements Variable {
|
|||||||
|
|
||||||
var sortType = Math.ceil(sortOrder / 2);
|
var sortType = Math.ceil(sortOrder / 2);
|
||||||
var reverseSort = (sortOrder % 2 === 0);
|
var reverseSort = (sortOrder % 2 === 0);
|
||||||
|
|
||||||
if (sortType === 1) {
|
if (sortType === 1) {
|
||||||
options = _.sortBy(options, 'text');
|
options = _.sortBy(options, 'text');
|
||||||
} else if (sortType === 2) {
|
} else if (sortType === 2) {
|
||||||
options = _.sortBy(options, function(opt) {
|
options = _.sortBy(options, function(opt) {
|
||||||
var matches = opt.text.match(new RegExp(".*?(\d+).*"));
|
var matches = opt.text.match(/.*?(\d+).*/);
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return parseInt(matches[1], 10);
|
return parseInt(matches[1], 10);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reverseSort) {
|
if (reverseSort) {
|
||||||
options = options.reverse();
|
options = options.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependsOn(variableName) {
|
||||||
|
return containsVariable(this.query, variableName) || containsVariable(this.datasource, variableName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variableConstructorMap['query'] = QueryVariable;
|
variableConstructorMap['query'] = QueryVariable;
|
||||||
|
36
public/app/features/templating/specs/variable_specs.ts
Normal file
36
public/app/features/templating/specs/variable_specs.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||||
|
|
||||||
|
import {containsVariable} from '../variable';
|
||||||
|
|
||||||
|
describe('containsVariable', function() {
|
||||||
|
|
||||||
|
describe('when checking if a string contains a variable', function() {
|
||||||
|
|
||||||
|
it('should find it with $var syntax', function() {
|
||||||
|
var contains = containsVariable('this.$test.filters', 'test');
|
||||||
|
expect(contains).to.be(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not find it if only part matches with $var syntax', function() {
|
||||||
|
var contains = containsVariable('this.$ServerDomain.filters', 'Server');
|
||||||
|
expect(contains).to.be(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find it with [[var]] syntax', function() {
|
||||||
|
var contains = containsVariable('this.[[test]].filters', 'test');
|
||||||
|
expect(contains).to.be(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find it when part of segment', function() {
|
||||||
|
var contains = containsVariable('metrics.$env.$group-*', 'group');
|
||||||
|
expect(contains).to.be(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find it its the only thing', function() {
|
||||||
|
var contains = containsVariable('$env', 'env');
|
||||||
|
expect(contains).to.be(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -4,7 +4,7 @@ import moment from 'moment';
|
|||||||
import helpers from 'test/specs/helpers';
|
import helpers from 'test/specs/helpers';
|
||||||
import '../all';
|
import '../all';
|
||||||
|
|
||||||
describe.only('VariableSrv', function() {
|
describe('VariableSrv', function() {
|
||||||
var ctx = new helpers.ControllerTestContext();
|
var ctx = new helpers.ControllerTestContext();
|
||||||
|
|
||||||
beforeEach(angularMocks.module('grafana.core'));
|
beforeEach(angularMocks.module('grafana.core'));
|
||||||
@ -15,11 +15,58 @@ describe.only('VariableSrv', function() {
|
|||||||
beforeEach(angularMocks.inject(($rootScope, $q, $location, $injector) => {
|
beforeEach(angularMocks.inject(($rootScope, $q, $location, $injector) => {
|
||||||
ctx.$q = $q;
|
ctx.$q = $q;
|
||||||
ctx.$rootScope = $rootScope;
|
ctx.$rootScope = $rootScope;
|
||||||
|
ctx.$location = $location;
|
||||||
ctx.variableSrv = $injector.get('variableSrv');
|
ctx.variableSrv = $injector.get('variableSrv');
|
||||||
ctx.variableSrv.init({templating: {list: []}});
|
ctx.variableSrv.init({templating: {list: []}});
|
||||||
ctx.$rootScope.$digest();
|
ctx.$rootScope.$digest();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function describeInitSceneario(desc, fn) {
|
||||||
|
describe(desc, function() {
|
||||||
|
var scenario: any = {
|
||||||
|
urlParams: {},
|
||||||
|
setup: setupFn => {
|
||||||
|
scenario.setupFn = setupFn;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
scenario.setupFn();
|
||||||
|
var ds: any = {};
|
||||||
|
ds.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
|
||||||
|
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ds));
|
||||||
|
ctx.datasourceSrv.getMetricSources = sinon.stub().returns(scenario.metricSources);
|
||||||
|
|
||||||
|
ctx.$location.search = sinon.stub().returns(scenario.urlParams);
|
||||||
|
|
||||||
|
ctx.dashboard = {templating: {list: scenario.variables}};
|
||||||
|
ctx.variableSrv.init(ctx.dashboard);
|
||||||
|
ctx.$rootScope.$digest();
|
||||||
|
|
||||||
|
scenario.variables = ctx.variableSrv.variables;
|
||||||
|
});
|
||||||
|
|
||||||
|
fn(scenario);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describeInitSceneario('when setting simple variable via url', scenario => {
|
||||||
|
scenario.setup(() => {
|
||||||
|
scenario.variables = [{
|
||||||
|
name: 'apps',
|
||||||
|
type: 'query',
|
||||||
|
current: {text: "test", value: "test"},
|
||||||
|
options: [{text: "test", value: "test"}]
|
||||||
|
}];
|
||||||
|
scenario.urlParams["var-apps"] = "new";
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update current value', () => {
|
||||||
|
expect(scenario.variables[0].current.value).to.be("new");
|
||||||
|
expect(scenario.variables[0].current.text).to.be("new");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function describeUpdateVariable(desc, fn) {
|
function describeUpdateVariable(desc, fn) {
|
||||||
describe(desc, function() {
|
describe(desc, function() {
|
||||||
var scenario: any = {};
|
var scenario: any = {};
|
||||||
@ -32,6 +79,8 @@ describe.only('VariableSrv', function() {
|
|||||||
var ds: any = {};
|
var ds: any = {};
|
||||||
ds.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
|
ds.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
|
||||||
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ds));
|
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ds));
|
||||||
|
ctx.datasourceSrv.getMetricSources = sinon.stub().returns(scenario.metricSources);
|
||||||
|
|
||||||
|
|
||||||
scenario.variable = ctx.variableSrv.addVariable(scenario.variableModel);
|
scenario.variable = ctx.variableSrv.addVariable(scenario.variableModel);
|
||||||
ctx.variableSrv.updateOptions(scenario.variable);
|
ctx.variableSrv.updateOptions(scenario.variable);
|
||||||
@ -274,6 +323,114 @@ describe.only('VariableSrv', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('without sort', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 0};
|
||||||
|
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return options without sort', function() {
|
||||||
|
expect(scenario.variable.options[0].text).to.be('bbb2');
|
||||||
|
expect(scenario.variable.options[1].text).to.be('aaa10');
|
||||||
|
expect(scenario.variable.options[2].text).to.be('ccc3');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('with alphabetical sort (asc)', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 1};
|
||||||
|
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return options with alphabetical sort', function() {
|
||||||
|
expect(scenario.variable.options[0].text).to.be('aaa10');
|
||||||
|
expect(scenario.variable.options[1].text).to.be('bbb2');
|
||||||
|
expect(scenario.variable.options[2].text).to.be('ccc3');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('with alphabetical sort (desc)', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 2};
|
||||||
|
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return options with alphabetical sort', function() {
|
||||||
|
expect(scenario.variable.options[0].text).to.be('ccc3');
|
||||||
|
expect(scenario.variable.options[1].text).to.be('bbb2');
|
||||||
|
expect(scenario.variable.options[2].text).to.be('aaa10');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('with numerical sort (asc)', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 3};
|
||||||
|
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return options with numerical sort', function() {
|
||||||
|
expect(scenario.variable.options[0].text).to.be('bbb2');
|
||||||
|
expect(scenario.variable.options[1].text).to.be('ccc3');
|
||||||
|
expect(scenario.variable.options[2].text).to.be('aaa10');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeUpdateVariable('with numerical sort (desc)', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'query', query: 'apps.*', name: 'test', sort: 4};
|
||||||
|
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return options with numerical sort', function() {
|
||||||
|
expect(scenario.variable.options[0].text).to.be('aaa10');
|
||||||
|
expect(scenario.variable.options[1].text).to.be('ccc3');
|
||||||
|
expect(scenario.variable.options[2].text).to.be('bbb2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// datasource variable update
|
||||||
|
//
|
||||||
|
describeUpdateVariable('datasource variable with regex filter', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {
|
||||||
|
type: 'datasource',
|
||||||
|
query: 'graphite',
|
||||||
|
name: 'test',
|
||||||
|
current: {value: 'backend4_pee', text: 'backend4_pee'},
|
||||||
|
regex: '/pee$/'
|
||||||
|
};
|
||||||
|
scenario.metricSources = [
|
||||||
|
{name: 'backend1', meta: {id: 'influx'}},
|
||||||
|
{name: 'backend2_pee', meta: {id: 'graphite'}},
|
||||||
|
{name: 'backend3', meta: {id: 'graphite'}},
|
||||||
|
{name: 'backend4_pee', meta: {id: 'graphite'}},
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set only contain graphite ds and filtered using regex', function() {
|
||||||
|
expect(scenario.variable.options.length).to.be(2);
|
||||||
|
expect(scenario.variable.options[0].value).to.be('backend2_pee');
|
||||||
|
expect(scenario.variable.options[1].value).to.be('backend4_pee');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep current value if available', function() {
|
||||||
|
expect(scenario.variable.current.value).to.be('backend4_pee');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom variable update
|
||||||
|
//
|
||||||
|
describeUpdateVariable('update custom variable', function(scenario) {
|
||||||
|
scenario.setup(function() {
|
||||||
|
scenario.variableModel = {type: 'custom', query: 'hej, hop, asd', name: 'test'};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update options array', function() {
|
||||||
|
expect(scenario.variable.options.length).to.be(3);
|
||||||
|
expect(scenario.variable.options[0].text).to.be('hej');
|
||||||
|
expect(scenario.variable.options[1].value).to.be('hop');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
define([
|
define([
|
||||||
'angular',
|
'angular',
|
||||||
'lodash',
|
'lodash',
|
||||||
|
'app/core/utils/kbn',
|
||||||
],
|
],
|
||||||
function (angular, _) {
|
function (angular, _, kbn) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var module = angular.module('grafana.services');
|
var module = angular.module('grafana.services');
|
||||||
@ -32,10 +33,6 @@ function (angular, _) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function regexEscape(value) {
|
|
||||||
return value.replace(/[\\^$*+?.()|[\]{}\/]/g, '\\$&');
|
|
||||||
}
|
|
||||||
|
|
||||||
function luceneEscape(value) {
|
function luceneEscape(value) {
|
||||||
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
|
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
|
||||||
}
|
}
|
||||||
@ -61,10 +58,10 @@ function (angular, _) {
|
|||||||
switch(format) {
|
switch(format) {
|
||||||
case "regex": {
|
case "regex": {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
return regexEscape(value);
|
return kbn.regexEscape(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var escapedValues = _.map(value, regexEscape);
|
var escapedValues = _.map(value, kbn.regexEscape);
|
||||||
return '(' + escapedValues.join('|') + ')';
|
return '(' + escapedValues.join('|') + ')';
|
||||||
}
|
}
|
||||||
case "lucene": {
|
case "lucene": {
|
||||||
@ -95,17 +92,6 @@ function (angular, _) {
|
|||||||
return match && (self._index[match[1] || match[2]] !== void 0);
|
return match && (self._index[match[1] || match[2]] !== void 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.containsVariable = function(str, variableName) {
|
|
||||||
if (!str) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
variableName = regexEscape(variableName);
|
|
||||||
var findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
|
|
||||||
var match = findVarRegex.exec(str);
|
|
||||||
return match !== null;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.highlightVariablesAsHtml = function(str) {
|
this.highlightVariablesAsHtml = function(str) {
|
||||||
if (!str || !_.isString(str)) { return str; }
|
if (!str || !_.isString(str)) { return str; }
|
||||||
|
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
|
|
||||||
|
import kbn from 'app/core/utils/kbn';
|
||||||
|
|
||||||
|
export function containsVariable(str, variableName) {
|
||||||
|
if (!str) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
variableName = kbn.regexEscape(variableName);
|
||||||
|
var findVarRegex = new RegExp('\\$(' + variableName + ')(?:\\W|$)|\\[\\[(' + variableName + ')\\]\\]', 'g');
|
||||||
|
var match = findVarRegex.exec(str);
|
||||||
|
return match !== null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Variable {
|
export interface Variable {
|
||||||
setValue(option);
|
setValue(option);
|
||||||
|
updateOptions();
|
||||||
|
dependsOn(variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,52 @@ export class VariableSrv {
|
|||||||
dashboard.templating.list.map(this.addVariable.bind(this));
|
dashboard.templating.list.map(this.addVariable.bind(this));
|
||||||
this.templateSrv.init(this.variables);
|
this.templateSrv.init(this.variables);
|
||||||
|
|
||||||
return this.$q.when();
|
var queryParams = this.$location.search();
|
||||||
|
|
||||||
|
for (let variable of this.variables) {
|
||||||
|
this.variableLock[variable.name] = this.$q.defer();
|
||||||
|
}
|
||||||
|
|
||||||
|
var promises = [];
|
||||||
|
|
||||||
|
for (let variable of this.variables) {
|
||||||
|
promises.push(this.processVariable(variable, queryParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$q.all(this.variables.map(variable => {
|
||||||
|
return this.processVariable(variable, queryParams);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
processVariable(variable, queryParams) {
|
||||||
|
var dependencies = [];
|
||||||
|
var lock = this.variableLock[variable.name];
|
||||||
|
|
||||||
|
for (let otherVariable of this.variables) {
|
||||||
|
if (variable.dependsOn(otherVariable)) {
|
||||||
|
dependencies.push(this.variableLock[otherVariable.name].promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$q.all(dependencies).then(() => {
|
||||||
|
var urlValue = queryParams['var-' + variable.name];
|
||||||
|
if (urlValue !== void 0) {
|
||||||
|
return variable.setValueFromUrl(urlValue).then(lock.resolve);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (variable.refresh === 1 || variable.refresh === 2) {
|
||||||
|
return variable.updateOptions().then(() => {
|
||||||
|
// if (_.isEmpty(variable.current) && variable.options.length) {
|
||||||
|
// self.setVariableValue(variable, variable.options[0]);
|
||||||
|
// }
|
||||||
|
lock.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.resolve();
|
||||||
|
}).finally(() => {
|
||||||
|
delete this.variableLock[variable.name];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addVariable(model) {
|
addVariable(model) {
|
||||||
@ -60,14 +105,13 @@ export class VariableSrv {
|
|||||||
return this.$q.when();
|
return this.$q.when();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cascade updates to variables that use this variable
|
||||||
var promises = _.map(this.variables, otherVariable => {
|
var promises = _.map(this.variables, otherVariable => {
|
||||||
if (otherVariable === variable) {
|
if (otherVariable === variable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.templateSrv.containsVariable(otherVariable.regex, variable.name) ||
|
if (otherVariable.dependsOn(variable)) {
|
||||||
this.templateSrv.containsVariable(otherVariable.query, variable.name) ||
|
|
||||||
this.templateSrv.containsVariable(otherVariable.datasource, variable.name)) {
|
|
||||||
return this.updateOptions(otherVariable);
|
return this.updateOptions(otherVariable);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -101,7 +145,7 @@ export class VariableSrv {
|
|||||||
|
|
||||||
validateVariableSelectionState(variable) {
|
validateVariableSelectionState(variable) {
|
||||||
if (!variable.current) {
|
if (!variable.current) {
|
||||||
if (!variable.options.length) { return Promise.resolve(); }
|
if (!variable.options.length) { return this.$q.when(); }
|
||||||
return variable.setValue(variable.options[0]);
|
return variable.setValue(variable.options[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +173,7 @@ export class VariableSrv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
coreModule.service('variableSrv', VariableSrv);
|
coreModule.service('variableSrv', VariableSrv);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import kbn from 'app/core/utils/kbn';
|
|
||||||
|
|
||||||
import * as dateMath from 'app/core/utils/datemath';
|
import * as dateMath from 'app/core/utils/datemath';
|
||||||
import PrometheusMetricFindQuery from './metric_find_query';
|
import PrometheusMetricFindQuery from './metric_find_query';
|
||||||
@ -41,6 +40,10 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
|||||||
return backendSrv.datasourceRequest(options);
|
return backendSrv.datasourceRequest(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function prometheusSpecialRegexEscape(value) {
|
||||||
|
return value.replace(/[\\^$*+?.()|[\]{}]/g, '\\\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
this.interpolateQueryExpr = function(value, variable, defaultFormatFn) {
|
this.interpolateQueryExpr = function(value, variable, defaultFormatFn) {
|
||||||
// if no multi or include all do not regexEscape
|
// if no multi or include all do not regexEscape
|
||||||
if (!variable.multi && !variable.includeAll) {
|
if (!variable.multi && !variable.includeAll) {
|
||||||
@ -48,10 +51,10 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
return kbn.regexEscape(value);
|
return prometheusSpecialRegexEscape(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var escapedValues = _.map(value, kbn.regexEscape);
|
var escapedValues = _.map(value, prometheusSpecialRegexEscape);
|
||||||
return escapedValues.join('|');
|
return escapedValues.join('|');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,38 +177,6 @@ define([
|
|||||||
var result = _templateSrv.highlightVariablesAsHtml('this $google ok');
|
var result = _templateSrv.highlightVariablesAsHtml('this $google ok');
|
||||||
expect(result).to.be('this $google ok');
|
expect(result).to.be('this $google ok');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when checking if a string contains a variable', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
_templateSrv.init([{ name: 'test', current: { value: 'muuuu' } }]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should find it with $var syntax', function() {
|
|
||||||
var contains = _templateSrv.containsVariable('this.$test.filters', 'test');
|
|
||||||
expect(contains).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not find it if only part matches with $var syntax', function() {
|
|
||||||
var contains = _templateSrv.containsVariable('this.$ServerDomain.filters', 'Server');
|
|
||||||
expect(contains).to.be(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should find it with [[var]] syntax', function() {
|
|
||||||
var contains = _templateSrv.containsVariable('this.[[test]].filters', 'test');
|
|
||||||
expect(contains).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should find it when part of segment', function() {
|
|
||||||
var contains = _templateSrv.containsVariable('metrics.$env.$group-*', 'group');
|
|
||||||
expect(contains).to.be(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should find it its the only thing', function() {
|
|
||||||
var contains = _templateSrv.containsVariable('$env', 'env');
|
|
||||||
expect(contains).to.be(true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateTemplateData with simple value', function() {
|
describe('updateTemplateData with simple value', function() {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
define([
|
define([
|
||||||
'../mocks/dashboard-mock',
|
'../mocks/dashboard-mock',
|
||||||
'./helpers',
|
'./helpers',
|
||||||
'moment',
|
|
||||||
'app/features/templating/templateValuesSrv'
|
'app/features/templating/templateValuesSrv'
|
||||||
], function(dashboardMock, helpers, moment) {
|
], function(dashboardMock, helpers) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('templateValuesSrv', function() {
|
describe('templateValuesSrv', function() {
|
||||||
@ -13,20 +12,6 @@ define([
|
|||||||
beforeEach(ctx.providePhase(['datasourceSrv', 'timeSrv', 'templateSrv', '$location']));
|
beforeEach(ctx.providePhase(['datasourceSrv', 'timeSrv', 'templateSrv', '$location']));
|
||||||
beforeEach(ctx.createService('templateValuesSrv'));
|
beforeEach(ctx.createService('templateValuesSrv'));
|
||||||
|
|
||||||
describe('update interval variable options', function() {
|
|
||||||
var variable = { type: 'interval', query: 'auto,1s,2h,5h,1d', name: 'test' };
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
ctx.service.updateOptions(variable);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(variable.options.length).to.be(5);
|
|
||||||
expect(variable.options[1].text).to.be('1s');
|
|
||||||
expect(variable.options[1].value).to.be('1s');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when template variable is present in url', function() {
|
describe('when template variable is present in url', function() {
|
||||||
describe('and setting simple variable', function() {
|
describe('and setting simple variable', function() {
|
||||||
var variable = {
|
var variable = {
|
||||||
@ -99,375 +84,6 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function describeUpdateVariable(desc, fn) {
|
|
||||||
describe(desc, function() {
|
|
||||||
var scenario = {};
|
|
||||||
scenario.setup = function(setupFn) {
|
|
||||||
scenario.setupFn = setupFn;
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
scenario.setupFn();
|
|
||||||
var ds = {};
|
|
||||||
ds.metricFindQuery = sinon.stub().returns(ctx.$q.when(scenario.queryResult));
|
|
||||||
ctx.datasourceSrv.get = sinon.stub().returns(ctx.$q.when(ds));
|
|
||||||
ctx.datasourceSrv.getMetricSources = sinon.stub().returns(scenario.metricSources);
|
|
||||||
|
|
||||||
ctx.service.updateOptions(scenario.variable);
|
|
||||||
ctx.$rootScope.$digest();
|
|
||||||
});
|
|
||||||
|
|
||||||
fn(scenario);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describeUpdateVariable('interval variable without auto', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'interval', query: '1s,2h,5h,1d', name: 'test' };
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(4);
|
|
||||||
expect(scenario.variable.options[0].text).to.be('1s');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('1s');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('query variable with empty current object and refresh', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: '', name: 'test', current: {} };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set current value to first option', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(2);
|
|
||||||
expect(scenario.variable.current.value).to.be('backend1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('query variable with multi select and new options does not contain some selected values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {
|
|
||||||
type: 'query',
|
|
||||||
query: '',
|
|
||||||
name: 'test',
|
|
||||||
current: {
|
|
||||||
value: ['val1', 'val2', 'val3'],
|
|
||||||
text: 'val1 + val2 + val3'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scenario.queryResult = [{text: 'val2'}, {text: 'val3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update current value', function() {
|
|
||||||
expect(scenario.variable.current.value).to.eql(['val2', 'val3']);
|
|
||||||
expect(scenario.variable.current.text).to.eql('val2 + val3');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('query variable with multi select and new options does not contain any selected values', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {
|
|
||||||
type: 'query',
|
|
||||||
query: '',
|
|
||||||
name: 'test',
|
|
||||||
current: {
|
|
||||||
value: ['val1', 'val2', 'val3'],
|
|
||||||
text: 'val1 + val2 + val3'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scenario.queryResult = [{text: 'val5'}, {text: 'val6'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update current value with first one', function() {
|
|
||||||
expect(scenario.variable.current.value).to.eql('val5');
|
|
||||||
expect(scenario.variable.current.text).to.eql('val5');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('query variable with multi select and $__all selected', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {
|
|
||||||
type: 'query',
|
|
||||||
query: '',
|
|
||||||
name: 'test',
|
|
||||||
includeAll: true,
|
|
||||||
current: {
|
|
||||||
value: ['$__all'],
|
|
||||||
text: 'All'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
scenario.queryResult = [{text: 'val5'}, {text: 'val6'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep current All value', function() {
|
|
||||||
expect(scenario.variable.current.value).to.eql(['$__all']);
|
|
||||||
expect(scenario.variable.current.text).to.eql('All');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('query variable with numeric results', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: '', name: 'test', current: {} };
|
|
||||||
scenario.queryResult = [{text: 12, value: 12}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set current value to first option', function() {
|
|
||||||
expect(scenario.variable.current.value).to.be('12');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('12');
|
|
||||||
expect(scenario.variable.options[0].text).to.be('12');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('interval variable without auto', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'interval', query: '1s,2h,5h,1d', name: 'test' };
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(4);
|
|
||||||
expect(scenario.variable.options[0].text).to.be('1s');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('1s');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('interval variable with auto', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'interval', query: '1s,2h,5h,1d', name: 'test', auto: true, auto_count: 10 };
|
|
||||||
|
|
||||||
var range = {
|
|
||||||
from: moment(new Date()).subtract(7, 'days').toDate(),
|
|
||||||
to: new Date()
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.timeSrv.timeRange = sinon.stub().returns(range);
|
|
||||||
ctx.templateSrv.setGrafanaVariable = sinon.spy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(5);
|
|
||||||
expect(scenario.variable.options[0].text).to.be('auto');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('$__auto_interval');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set $__auto_interval', function() {
|
|
||||||
var call = ctx.templateSrv.setGrafanaVariable.getCall(0);
|
|
||||||
expect(call.args[0]).to.be('$__auto_interval');
|
|
||||||
expect(call.args[1]).to.be('12h');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('update custom variable', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'custom', query: 'hej, hop, asd', name: 'test'};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(3);
|
|
||||||
expect(scenario.variable.options[0].text).to.be('hej');
|
|
||||||
expect(scenario.variable.options[1].value).to.be('hop');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set $__auto_interval', function() {
|
|
||||||
var call = ctx.templateSrv.setGrafanaVariable.getCall(0);
|
|
||||||
expect(call.args[0]).to.be('$__auto_interval');
|
|
||||||
expect(call.args[1]).to.be('12h');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('basic query variable', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update options array', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(2);
|
|
||||||
expect(scenario.variable.options[0].text).to.be('backend1');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('backend1');
|
|
||||||
expect(scenario.variable.options[1].value).to.be('backend2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should select first option as value', function() {
|
|
||||||
expect(scenario.variable.current.value).to.be('backend1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('and existing value still exists in options', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.variable.current = { value: 'backend2', text: 'backend2'};
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep variable value', function() {
|
|
||||||
expect(scenario.variable.current.text).to.be('backend2');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('and regex pattern exists', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.variable.regex = '/apps.*(backend_[0-9]+)/';
|
|
||||||
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should extract and use match group', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('backend_01');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('and regex pattern exists and no match', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.variable.regex = '/apps.*(backendasd[0-9]+)/';
|
|
||||||
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not add non matching items, None option should be added instead', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(1);
|
|
||||||
expect(scenario.variable.options[0].isNone).to.be(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('regex pattern without slashes', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.variable.regex = 'backend_01';
|
|
||||||
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_02.counters.req'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return matches options', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('regex pattern remove duplicates', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test' };
|
|
||||||
scenario.variable.regex = 'backend_01';
|
|
||||||
scenario.queryResult = [{text: 'apps.backend.backend_01.counters.req'}, {text: 'apps.backend.backend_01.counters.req'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return matches options', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include All', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', includeAll: true};
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add All option', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('All');
|
|
||||||
expect(scenario.variable.options[0].value).to.be('$__all');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with include all and custom value', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = { type: 'query', query: 'apps.*', name: 'test', includeAll: true, allValue: '*' };
|
|
||||||
scenario.queryResult = [{text: 'backend1'}, {text: 'backend2'}, { text: 'backend3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add All option with custom value', function() {
|
|
||||||
expect(scenario.variable.options[0].value).to.be('$__all');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('datasource variable with regex filter', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {
|
|
||||||
type: 'datasource',
|
|
||||||
query: 'graphite',
|
|
||||||
name: 'test',
|
|
||||||
current: {value: 'backend4_pee', text: 'backend4_pee'},
|
|
||||||
regex: '/pee$/'
|
|
||||||
};
|
|
||||||
scenario.metricSources = [
|
|
||||||
{name: 'backend1', meta: {id: 'influx'}},
|
|
||||||
{name: 'backend2_pee', meta: {id: 'graphite'}},
|
|
||||||
{name: 'backend3', meta: {id: 'graphite'}},
|
|
||||||
{name: 'backend4_pee', meta: {id: 'graphite'}},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set only contain graphite ds and filtered using regex', function() {
|
|
||||||
expect(scenario.variable.options.length).to.be(2);
|
|
||||||
expect(scenario.variable.options[0].value).to.be('backend2_pee');
|
|
||||||
expect(scenario.variable.options[1].value).to.be('backend4_pee');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep current value if available', function() {
|
|
||||||
expect(scenario.variable.current.value).to.be('backend4_pee');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('without sort', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 0};
|
|
||||||
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return options without sort', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('bbb2');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('aaa10');
|
|
||||||
expect(scenario.variable.options[2].text).to.be('ccc3');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with alphabetical sort (asc)', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 1};
|
|
||||||
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return options with alphabetical sort', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('aaa10');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('bbb2');
|
|
||||||
expect(scenario.variable.options[2].text).to.be('ccc3');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with alphabetical sort (desc)', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 2};
|
|
||||||
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return options with alphabetical sort', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('ccc3');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('bbb2');
|
|
||||||
expect(scenario.variable.options[2].text).to.be('aaa10');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with numerical sort (asc)', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 3};
|
|
||||||
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return options with numerical sort', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('bbb2');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('ccc3');
|
|
||||||
expect(scenario.variable.options[2].text).to.be('aaa10');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describeUpdateVariable('with numerical sort (desc)', function(scenario) {
|
|
||||||
scenario.setup(function() {
|
|
||||||
scenario.variable = {type: 'query', query: 'apps.*', name: 'test', sort: 4};
|
|
||||||
scenario.queryResult = [{text: 'bbb2'}, {text: 'aaa10'}, { text: 'ccc3'}];
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return options with numerical sort', function() {
|
|
||||||
expect(scenario.variable.options[0].text).to.be('aaa10');
|
|
||||||
expect(scenario.variable.options[1].text).to.be('ccc3');
|
|
||||||
expect(scenario.variable.options[2].text).to.be('bbb2');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user