feat(adhoc filters): good progress on ad hoc filters and sync from to url, #6038
This commit is contained in:
@@ -21,7 +21,7 @@ export class AdHocFiltersCtrl {
|
||||
if (this.variable.value && !_.isArray(this.variable.value)) {
|
||||
}
|
||||
|
||||
for (let tag of this.variable.tags) {
|
||||
for (let tag of this.variable.filters) {
|
||||
if (this.segments.length > 0) {
|
||||
this.segments.push(this.uiSegmentSrv.newCondition('AND'));
|
||||
}
|
||||
@@ -38,7 +38,11 @@ export class AdHocFiltersCtrl {
|
||||
|
||||
getOptions(segment, index) {
|
||||
if (segment.type === 'operator') {
|
||||
return this.$q.when(this.uiSegmentSrv.newOperators(['=', '!=', '<>', '<', '>', '=~', '!~']));
|
||||
return this.$q.when(this.uiSegmentSrv.newOperators(['=', '!=', '<', '>', '=~', '!~']));
|
||||
}
|
||||
|
||||
if (segment.type === 'condition') {
|
||||
return this.$q.when([this.uiSegmentSrv.newSegment('AND')]);
|
||||
}
|
||||
|
||||
return this.datasourceSrv.get(this.variable.datasource).then(ds => {
|
||||
@@ -100,37 +104,45 @@ export class AdHocFiltersCtrl {
|
||||
}
|
||||
|
||||
updateVariableModel() {
|
||||
var tags = [];
|
||||
var tagIndex = -1;
|
||||
var tagOperator = "";
|
||||
var filters = [];
|
||||
var filterIndex = -1;
|
||||
var operator = "";
|
||||
var hasFakes = false;
|
||||
|
||||
this.segments.forEach((segment, index) => {
|
||||
if (segment.fake) {
|
||||
this.segments.forEach(segment => {
|
||||
if (segment.type === 'value' && segment.fake) {
|
||||
hasFakes = true;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (segment.type) {
|
||||
case 'key': {
|
||||
tags.push({key: segment.value});
|
||||
tagIndex += 1;
|
||||
filters.push({key: segment.value});
|
||||
filterIndex += 1;
|
||||
break;
|
||||
}
|
||||
case 'value': {
|
||||
tags[tagIndex].value = segment.value;
|
||||
filters[filterIndex].value = segment.value;
|
||||
break;
|
||||
}
|
||||
case 'operator': {
|
||||
tags[tagIndex].operator = segment.value;
|
||||
filters[filterIndex].operator = segment.value;
|
||||
break;
|
||||
}
|
||||
case 'condition': {
|
||||
filters[filterIndex].condition = segment.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (hasFakes) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.variable.setFilters(filters);
|
||||
this.$rootScope.$emit('template-variable-value-updated');
|
||||
this.$rootScope.$broadcast('refresh');
|
||||
this.variable.tags = tags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ function (angular, _, $) {
|
||||
$location.search(urlParams);
|
||||
});
|
||||
|
||||
$scope.onAppEvent('template-variable-value-updated', function() {
|
||||
self.updateUrlParamsWithCurrentVariables();
|
||||
});
|
||||
|
||||
$scope.onAppEvent('$routeUpdate', function() {
|
||||
var urlState = self.getQueryStringState();
|
||||
if (self.needsSync(urlState)) {
|
||||
@@ -57,22 +53,6 @@ function (angular, _, $) {
|
||||
this.expandRowForPanel();
|
||||
}
|
||||
|
||||
DashboardViewState.prototype.updateUrlParamsWithCurrentVariables = function() {
|
||||
// update url
|
||||
var params = $location.search();
|
||||
// remove variable params
|
||||
_.each(params, function(value, key) {
|
||||
if (key.indexOf('var-') === 0) {
|
||||
delete params[key];
|
||||
}
|
||||
});
|
||||
|
||||
// add new values
|
||||
templateSrv.fillVariableValuesForUrl(params);
|
||||
// update url
|
||||
$location.search(params);
|
||||
};
|
||||
|
||||
DashboardViewState.prototype.expandRowForPanel = function() {
|
||||
if (!this.state.panelId) { return; }
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {Variable, assignModelProperties, variableTypes} from './variable';
|
||||
import {VariableSrv} from './variable_srv';
|
||||
|
||||
export class AdhocVariable implements Variable {
|
||||
filters: any[];
|
||||
|
||||
defaults = {
|
||||
type: 'adhoc',
|
||||
@@ -13,9 +14,7 @@ export class AdhocVariable implements Variable {
|
||||
label: '',
|
||||
hide: 0,
|
||||
datasource: null,
|
||||
options: [],
|
||||
current: {},
|
||||
tags: {},
|
||||
filters: [],
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
@@ -41,8 +40,31 @@ export class AdhocVariable implements Variable {
|
||||
}
|
||||
|
||||
setValueFromUrl(urlValue) {
|
||||
if (!_.isArray(urlValue)) {
|
||||
urlValue = [urlValue];
|
||||
}
|
||||
|
||||
this.filters = urlValue.map(item => {
|
||||
var values = item.split('|');
|
||||
return {
|
||||
key: values[0],
|
||||
operator: values[1],
|
||||
value: values[2],
|
||||
};
|
||||
});
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
return this.filters.map(filter => {
|
||||
return filter.key + '|' + filter.operator + '|' + filter.value;
|
||||
});
|
||||
}
|
||||
|
||||
setFilters(filters: any[]) {
|
||||
this.filters = filters;
|
||||
}
|
||||
}
|
||||
|
||||
variableTypes['adhoc'] = {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {VariableSrv} from './variable_srv';
|
||||
export class ConstantVariable implements Variable {
|
||||
query: string;
|
||||
options: any[];
|
||||
current: any;
|
||||
|
||||
defaults = {
|
||||
type: 'constant',
|
||||
@@ -14,6 +15,7 @@ export class ConstantVariable implements Variable {
|
||||
hide: 2,
|
||||
label: '',
|
||||
query: '',
|
||||
current: {},
|
||||
};
|
||||
|
||||
/** @ngInject */
|
||||
@@ -43,6 +45,11 @@ export class ConstantVariable implements Variable {
|
||||
setValueFromUrl(urlValue) {
|
||||
return this.variableSrv.setOptionFromUrl(this, urlValue);
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
return this.current.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
variableTypes['constant'] = {
|
||||
|
||||
@@ -10,6 +10,7 @@ export class CustomVariable implements Variable {
|
||||
options: any;
|
||||
includeAll: boolean;
|
||||
multi: boolean;
|
||||
current: any;
|
||||
|
||||
defaults = {
|
||||
type: 'custom',
|
||||
@@ -17,10 +18,11 @@ export class CustomVariable implements Variable {
|
||||
label: '',
|
||||
hide: 0,
|
||||
options: [],
|
||||
current: {text: '', value: ''},
|
||||
current: {},
|
||||
query: '',
|
||||
includeAll: false,
|
||||
multi: false,
|
||||
allValue: null,
|
||||
};
|
||||
|
||||
/** @ngInject **/
|
||||
@@ -61,6 +63,13 @@ export class CustomVariable implements Variable {
|
||||
setValueFromUrl(urlValue) {
|
||||
return this.variableSrv.setOptionFromUrl(this, urlValue);
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
if (this.current.text === 'All') {
|
||||
return 'All';
|
||||
}
|
||||
return this.current.value;
|
||||
}
|
||||
}
|
||||
|
||||
variableTypes['custom'] = {
|
||||
|
||||
@@ -9,13 +9,14 @@ export class DatasourceVariable implements Variable {
|
||||
regex: any;
|
||||
query: string;
|
||||
options: any;
|
||||
current: any;
|
||||
|
||||
defaults = {
|
||||
type: 'datasource',
|
||||
name: '',
|
||||
hide: 0,
|
||||
label: '',
|
||||
current: {text: '', value: ''},
|
||||
current: {},
|
||||
regex: '',
|
||||
options: [],
|
||||
query: '',
|
||||
@@ -73,6 +74,10 @@ export class DatasourceVariable implements Variable {
|
||||
setValueFromUrl(urlValue) {
|
||||
return this.variableSrv.setOptionFromUrl(this, urlValue);
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
return this.current.value;
|
||||
}
|
||||
}
|
||||
|
||||
variableTypes['datasource'] = {
|
||||
|
||||
@@ -12,6 +12,7 @@ export class IntervalVariable implements Variable {
|
||||
auto: boolean;
|
||||
query: string;
|
||||
refresh: number;
|
||||
current: any;
|
||||
|
||||
defaults = {
|
||||
type: 'interval',
|
||||
@@ -20,7 +21,7 @@ export class IntervalVariable implements Variable {
|
||||
label: '',
|
||||
refresh: 2,
|
||||
options: [],
|
||||
current: {text: '', value: ''},
|
||||
current: {},
|
||||
query: '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d',
|
||||
auto: false,
|
||||
auto_min: '10s',
|
||||
@@ -75,6 +76,10 @@ export class IntervalVariable implements Variable {
|
||||
this.updateAutoValue();
|
||||
return this.variableSrv.setOptionFromUrl(this, urlValue);
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
return this.current.value;
|
||||
}
|
||||
}
|
||||
|
||||
variableTypes['interval'] = {
|
||||
|
||||
@@ -33,8 +33,11 @@ export class QueryVariable implements Variable {
|
||||
name: '',
|
||||
multi: false,
|
||||
includeAll: false,
|
||||
allValue: null,
|
||||
options: [],
|
||||
current: {text: '', value: ''},
|
||||
current: {},
|
||||
tagsQuery: null,
|
||||
tagValuesQuery: null,
|
||||
};
|
||||
|
||||
constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private $q) {
|
||||
@@ -56,6 +59,13 @@ export class QueryVariable implements Variable {
|
||||
return this.variableSrv.setOptionFromUrl(this, urlValue);
|
||||
}
|
||||
|
||||
getValueForUrl() {
|
||||
if (this.current.text === 'All') {
|
||||
return 'All';
|
||||
}
|
||||
return this.current.value;
|
||||
}
|
||||
|
||||
updateOptions() {
|
||||
return this.datasourceSrv.get(this.datasource)
|
||||
.then(this.updateOptionsFromMetricFindQuery.bind(this))
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
|
||||
|
||||
import '../all';
|
||||
import {Emitter} from 'app/core/core';
|
||||
|
||||
describe('templateSrv', function() {
|
||||
var _templateSrv, _variableSrv;
|
||||
|
||||
beforeEach(angularMocks.module('grafana.core'));
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
|
||||
beforeEach(angularMocks.inject(function(variableSrv, templateSrv) {
|
||||
_templateSrv = templateSrv;
|
||||
_variableSrv = variableSrv;
|
||||
}));
|
||||
|
||||
function initTemplateSrv(variables) {
|
||||
_variableSrv.init({
|
||||
templating: {list: variables},
|
||||
events: new Emitter(),
|
||||
});
|
||||
}
|
||||
|
||||
describe('init', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'oogle'}}]);
|
||||
});
|
||||
|
||||
it('should initialize template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.oogle.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass scoped vars', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'oogle' }}]);
|
||||
});
|
||||
|
||||
it('should replace $test with scoped value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
|
||||
expect(target).to.be('this.mupp.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with scoped text', function() {
|
||||
var target = _templateSrv.replaceWithText('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
|
||||
expect(target).to.be('this.asd.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass multi / all format', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: {value: ['value1', 'value2'] }}]);
|
||||
});
|
||||
|
||||
it('should replace $test with globbed value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with piped value', function() {
|
||||
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||
expect(target).to.be('this=value1|value2');
|
||||
});
|
||||
|
||||
it('should replace $test with piped value', function() {
|
||||
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||
expect(target).to.be('this=value1|value2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{
|
||||
type: 'query',
|
||||
name: 'test',
|
||||
current: {value: '$__all' },
|
||||
options: [
|
||||
{value: '$__all'}, {value: 'value1'}, {value: 'value2'}
|
||||
]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.{value1,value2}.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option and custom value', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{
|
||||
type: 'query',
|
||||
name: 'test',
|
||||
current: {value: '$__all' },
|
||||
allValue: '*',
|
||||
options: [
|
||||
{value: 'value1'}, {value: 'value2'}
|
||||
]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.*.filters');
|
||||
});
|
||||
|
||||
it('should not escape custom all value', function() {
|
||||
var target = _templateSrv.replace('this.$test', {}, 'regex');
|
||||
expect(target).to.be('this.*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lucene format', function() {
|
||||
it('should properly escape $test with lucene escape sequences', function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: {value: 'value/4' }}]);
|
||||
var target = _templateSrv.replace('this:$test', {}, 'lucene');
|
||||
expect(target).to.be("this:value\\\/4");
|
||||
});
|
||||
});
|
||||
|
||||
describe('format variable to string values', function() {
|
||||
it('single value should return value', function() {
|
||||
var result = _templateSrv.formatValue('test');
|
||||
expect(result).to.be('test');
|
||||
});
|
||||
|
||||
it('multi value and glob format should render glob string', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'glob');
|
||||
expect(result).to.be('{test,test2}');
|
||||
});
|
||||
|
||||
it('multi value and lucene should render as lucene expr', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'lucene');
|
||||
expect(result).to.be('("test" OR "test2")');
|
||||
});
|
||||
|
||||
it('multi value and regex format should render regex string', function() {
|
||||
var result = _templateSrv.formatValue(['test.','test2'], 'regex');
|
||||
expect(result).to.be('(test\\.|test2)');
|
||||
});
|
||||
|
||||
it('multi value and pipe should render pipe string', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'pipe');
|
||||
expect(result).to.be('test|test2');
|
||||
});
|
||||
|
||||
it('slash should be properly escaped in regex format', function() {
|
||||
var result = _templateSrv.formatValue('Gi3/14', 'regex');
|
||||
expect(result).to.be('Gi3\\/14');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('can check if variable exists', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should return true if exists', function() {
|
||||
var result = _templateSrv.variableExists('$test');
|
||||
expect(result).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('can hightlight variables in string', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should insert html', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('$test');
|
||||
expect(result).to.be('<span class="template-variable">$test</span>');
|
||||
});
|
||||
|
||||
it('should insert html anywhere in string', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('this $test ok');
|
||||
expect(result).to.be('this <span class="template-variable">$test</span> ok');
|
||||
});
|
||||
|
||||
it('should ignore if variables does not exist', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('this $google ok');
|
||||
expect(result).to.be('this $google ok');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateTemplateData with simple value', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: 'muuuu' } }]);
|
||||
});
|
||||
|
||||
it('should set current value and update template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.muuuu.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: ['val1', 'val2'] }}]);
|
||||
});
|
||||
|
||||
it('should set multiple url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).to.eql(['val1', 'val2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value and scopedVars', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: ['val1', 'val2'] }}]);
|
||||
});
|
||||
|
||||
it('should set scoped value as url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params, {'test': {value: 'val1'}});
|
||||
expect(params['var-test']).to.eql('val1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replaceWithText', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([
|
||||
{type: 'query', name: 'server', current: { value: '{asd,asd2}', text: 'All' } },
|
||||
{type: 'interval', name: 'period', current: { value: '$__auto_interval', text: 'auto' } }
|
||||
]);
|
||||
_templateSrv.setGrafanaVariable('$__auto_interval', '13m');
|
||||
_templateSrv.updateTemplateData();
|
||||
});
|
||||
|
||||
it('should replace with text except for grafanaVariables', function() {
|
||||
var target = _templateSrv.replaceWithText('Server: $server, period: $period');
|
||||
expect(target).to.be('Server: All, period: 13m');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -180,18 +180,11 @@ function (angular, _, kbn) {
|
||||
|
||||
this.fillVariableValuesForUrl = function(params, scopedVars) {
|
||||
_.each(this.variables, function(variable) {
|
||||
var current = variable.current;
|
||||
var value = current.value;
|
||||
|
||||
if (current.text === 'All') {
|
||||
value = 'All';
|
||||
}
|
||||
|
||||
if (scopedVars && scopedVars[variable.name] !== void 0) {
|
||||
value = scopedVars[variable.name].value;
|
||||
params['var-' + variable.name] = scopedVars[variable.name].value;
|
||||
} else {
|
||||
params['var-' + variable.name] = variable.getValueForUrl();
|
||||
}
|
||||
|
||||
params['var-' + variable.name] = value;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ export interface Variable {
|
||||
updateOptions();
|
||||
dependsOn(variable);
|
||||
setValueFromUrl(urlValue);
|
||||
getValueForUrl();
|
||||
getModel();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ export class VariableSrv {
|
||||
constructor(private $rootScope, private $q, private $location, private $injector, private templateSrv) {
|
||||
// update time variant variables
|
||||
$rootScope.$on('refresh', this.onDashboardRefresh.bind(this), $rootScope);
|
||||
$rootScope.$on('template-variable-value-updated', this.updateUrlParamsWithCurrentVariables.bind(this), $rootScope);
|
||||
}
|
||||
|
||||
init(dashboard) {
|
||||
@@ -210,6 +211,23 @@ export class VariableSrv {
|
||||
this.selectOptionsForCurrentValue(variable);
|
||||
return this.variableUpdated(variable);
|
||||
}
|
||||
|
||||
updateUrlParamsWithCurrentVariables() {
|
||||
// update url
|
||||
var params = this.$location.search();
|
||||
|
||||
// remove variable params
|
||||
_.each(params, function(value, key) {
|
||||
if (key.indexOf('var-') === 0) {
|
||||
delete params[key];
|
||||
}
|
||||
});
|
||||
|
||||
// add new values
|
||||
this.templateSrv.fillVariableValuesForUrl(params);
|
||||
// update url
|
||||
this.$location.search(params);
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.service('variableSrv', VariableSrv);
|
||||
|
||||
@@ -56,9 +56,9 @@ export default class InfluxDatasource {
|
||||
// apply add hoc filters
|
||||
for (let variable of this.templateSrv.variables) {
|
||||
if (variable.type === 'adhoc' && variable.datasource === this.name) {
|
||||
for (let tag of variable.tags) {
|
||||
if (tag.key !== undefined && tag.value !== undefined) {
|
||||
target.tags.push({key: tag.key, value: tag.value, condition: 'AND'});
|
||||
for (let filter of variable.filters) {
|
||||
if (filter.key !== undefined && filter.value !== undefined) {
|
||||
target.tags.push({key: filter.key, value: filter.value, condition: filter.condition, operator: filter.operator});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
define([
|
||||
'../mocks/dashboard-mock',
|
||||
'lodash',
|
||||
'app/features/templating/templateSrv'
|
||||
], function(dashboardMock) {
|
||||
'use strict';
|
||||
|
||||
describe('templateSrv', function() {
|
||||
var _templateSrv;
|
||||
var _dashboard;
|
||||
|
||||
beforeEach(module('grafana.services'));
|
||||
beforeEach(module(function() {
|
||||
_dashboard = dashboardMock.create();
|
||||
}));
|
||||
|
||||
beforeEach(inject(function(templateSrv) {
|
||||
_templateSrv = templateSrv;
|
||||
}));
|
||||
|
||||
describe('init', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should initialize template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.oogle.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass scoped vars', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should replace $test with scoped value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
|
||||
expect(target).to.be('this.mupp.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with scoped text', function() {
|
||||
var target = _templateSrv.replaceWithText('this.$test.filters', {'test': {value: 'mupp', text: 'asd'}});
|
||||
expect(target).to.be('this.asd.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replace can pass multi / all format', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{name: 'test', current: {value: ['value1', 'value2'] }}]);
|
||||
});
|
||||
|
||||
it('should replace $test with globbed value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.{value1,value2}.filters');
|
||||
});
|
||||
|
||||
it('should replace $test with piped value', function() {
|
||||
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||
expect(target).to.be('this=value1|value2');
|
||||
});
|
||||
|
||||
it('should replace $test with piped value', function() {
|
||||
var target = _templateSrv.replace('this=$test', {}, 'pipe');
|
||||
expect(target).to.be('this=value1|value2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{
|
||||
name: 'test',
|
||||
current: {value: '$__all' },
|
||||
options: [
|
||||
{value: '$__all'}, {value: 'value1'}, {value: 'value2'}
|
||||
]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.{value1,value2}.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('variable with all option and custom value', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{
|
||||
name: 'test',
|
||||
current: {value: '$__all' },
|
||||
allValue: '*',
|
||||
options: [
|
||||
{value: 'value1'}, {value: 'value2'}
|
||||
]
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.*.filters');
|
||||
});
|
||||
|
||||
it('should not escape custom all value', function() {
|
||||
var target = _templateSrv.replace('this.$test', {}, 'regex');
|
||||
expect(target).to.be('this.*');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lucene format', function() {
|
||||
it('should properly escape $test with lucene escape sequences', function() {
|
||||
_templateSrv.init([{name: 'test', current: {value: 'value/4' }}]);
|
||||
var target = _templateSrv.replace('this:$test', {}, 'lucene');
|
||||
expect(target).to.be("this:value\\\/4");
|
||||
});
|
||||
});
|
||||
|
||||
describe('format variable to string values', function() {
|
||||
it('single value should return value', function() {
|
||||
var result = _templateSrv.formatValue('test');
|
||||
expect(result).to.be('test');
|
||||
});
|
||||
|
||||
it('multi value and glob format should render glob string', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'glob');
|
||||
expect(result).to.be('{test,test2}');
|
||||
});
|
||||
|
||||
it('multi value and lucene should render as lucene expr', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'lucene');
|
||||
expect(result).to.be('("test" OR "test2")');
|
||||
});
|
||||
|
||||
it('multi value and regex format should render regex string', function() {
|
||||
var result = _templateSrv.formatValue(['test.','test2'], 'regex');
|
||||
expect(result).to.be('(test\\.|test2)');
|
||||
});
|
||||
|
||||
it('multi value and pipe should render pipe string', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'pipe');
|
||||
expect(result).to.be('test|test2');
|
||||
});
|
||||
|
||||
it('slash should be properly escaped in regex format', function() {
|
||||
var result = _templateSrv.formatValue('Gi3/14', 'regex');
|
||||
expect(result).to.be('Gi3\\/14');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('can check if variable exists', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should return true if exists', function() {
|
||||
var result = _templateSrv.variableExists('$test');
|
||||
expect(result).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('can hightlight variables in string', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'oogle' } }]);
|
||||
});
|
||||
|
||||
it('should insert html', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('$test');
|
||||
expect(result).to.be('<span class="template-variable">$test</span>');
|
||||
});
|
||||
|
||||
it('should insert html anywhere in string', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('this $test ok');
|
||||
expect(result).to.be('this <span class="template-variable">$test</span> ok');
|
||||
});
|
||||
|
||||
it('should ignore if variables does not exist', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('this $google ok');
|
||||
expect(result).to.be('this $google ok');
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateTemplateData with simple value', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: 'muuuu' } }]);
|
||||
});
|
||||
|
||||
it('should set current value and update template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.muuuu.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: ['val1', 'val2'] }}]);
|
||||
});
|
||||
|
||||
it('should set multiple url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).to.eql(['val1', 'val2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value and scopedVars', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([{ name: 'test', current: { value: ['val1', 'val2'] }}]);
|
||||
});
|
||||
|
||||
it('should set multiple url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params, {'test': {value: 'val1'}});
|
||||
expect(params['var-test']).to.eql('val1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replaceWithText', function() {
|
||||
beforeEach(function() {
|
||||
_templateSrv.init([
|
||||
{ name: 'server', current: { value: '{asd,asd2}', text: 'All' } },
|
||||
{ name: 'period', current: { value: '$__auto_interval', text: 'auto' } }
|
||||
]);
|
||||
_templateSrv.setGrafanaVariable('$__auto_interval', '13m');
|
||||
_templateSrv.updateTemplateData();
|
||||
});
|
||||
|
||||
it('should replace with text except for grafanaVariables', function() {
|
||||
var target = _templateSrv.replaceWithText('Server: $server, period: $period');
|
||||
expect(target).to.be('Server: All, period: 13m');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user