From 6e429b8575edc2a6ec7c27bb276534676da21bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 20 Sep 2016 11:57:43 +0200 Subject: [PATCH] feat(adhoc filters): good progress on ad hoc filters and sync from to url, #6038 --- .../app/features/dashboard/ad_hoc_filters.ts | 36 ++- public/app/features/dashboard/viewStateSrv.js | 20 -- .../app/features/templating/adhoc_variable.ts | 28 ++- .../features/templating/constant_variable.ts | 7 + .../features/templating/custom_variable.ts | 11 +- .../templating/datasource_variable.ts | 7 +- .../features/templating/interval_variable.ts | 7 +- .../app/features/templating/query_variable.ts | 12 +- .../templating/specs/template_srv_specs.ts | 237 ++++++++++++++++++ public/app/features/templating/templateSrv.js | 13 +- public/app/features/templating/variable.ts | 1 + .../app/features/templating/variable_srv.ts | 18 ++ .../plugins/datasource/influxdb/datasource.ts | 6 +- public/test/specs/templateSrv-specs.js | 235 ----------------- 14 files changed, 351 insertions(+), 287 deletions(-) create mode 100644 public/app/features/templating/specs/template_srv_specs.ts delete mode 100644 public/test/specs/templateSrv-specs.js diff --git a/public/app/features/dashboard/ad_hoc_filters.ts b/public/app/features/dashboard/ad_hoc_filters.ts index 426f6162467..f962f8ca2f4 100644 --- a/public/app/features/dashboard/ad_hoc_filters.ts +++ b/public/app/features/dashboard/ad_hoc_filters.ts @@ -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; } } diff --git a/public/app/features/dashboard/viewStateSrv.js b/public/app/features/dashboard/viewStateSrv.js index 758d8ab7067..73f0c038c7f 100644 --- a/public/app/features/dashboard/viewStateSrv.js +++ b/public/app/features/dashboard/viewStateSrv.js @@ -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; } diff --git a/public/app/features/templating/adhoc_variable.ts b/public/app/features/templating/adhoc_variable.ts index 579b0268efa..ea942beaef3 100644 --- a/public/app/features/templating/adhoc_variable.ts +++ b/public/app/features/templating/adhoc_variable.ts @@ -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'] = { diff --git a/public/app/features/templating/constant_variable.ts b/public/app/features/templating/constant_variable.ts index f0a659e0c20..9fe2acfdfb2 100644 --- a/public/app/features/templating/constant_variable.ts +++ b/public/app/features/templating/constant_variable.ts @@ -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'] = { diff --git a/public/app/features/templating/custom_variable.ts b/public/app/features/templating/custom_variable.ts index 77dfd57cae8..90ce08cf9e4 100644 --- a/public/app/features/templating/custom_variable.ts +++ b/public/app/features/templating/custom_variable.ts @@ -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'] = { diff --git a/public/app/features/templating/datasource_variable.ts b/public/app/features/templating/datasource_variable.ts index b23b5e04e42..96776c31163 100644 --- a/public/app/features/templating/datasource_variable.ts +++ b/public/app/features/templating/datasource_variable.ts @@ -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'] = { diff --git a/public/app/features/templating/interval_variable.ts b/public/app/features/templating/interval_variable.ts index 94bb608e7e3..d53e44ae533 100644 --- a/public/app/features/templating/interval_variable.ts +++ b/public/app/features/templating/interval_variable.ts @@ -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'] = { diff --git a/public/app/features/templating/query_variable.ts b/public/app/features/templating/query_variable.ts index 5d6492849f4..a9ac6aa02b9 100644 --- a/public/app/features/templating/query_variable.ts +++ b/public/app/features/templating/query_variable.ts @@ -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)) diff --git a/public/app/features/templating/specs/template_srv_specs.ts b/public/app/features/templating/specs/template_srv_specs.ts new file mode 100644 index 00000000000..94b1e211293 --- /dev/null +++ b/public/app/features/templating/specs/template_srv_specs.ts @@ -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('$test'); + }); + + it('should insert html anywhere in string', function() { + var result = _templateSrv.highlightVariablesAsHtml('this $test ok'); + expect(result).to.be('this $test 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'); + }); + }); +}); diff --git a/public/app/features/templating/templateSrv.js b/public/app/features/templating/templateSrv.js index 7615aa7da0f..bca814d29a4 100644 --- a/public/app/features/templating/templateSrv.js +++ b/public/app/features/templating/templateSrv.js @@ -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; }); }; diff --git a/public/app/features/templating/variable.ts b/public/app/features/templating/variable.ts index 9a478b50840..3e12b65ec16 100644 --- a/public/app/features/templating/variable.ts +++ b/public/app/features/templating/variable.ts @@ -8,6 +8,7 @@ export interface Variable { updateOptions(); dependsOn(variable); setValueFromUrl(urlValue); + getValueForUrl(); getModel(); } diff --git a/public/app/features/templating/variable_srv.ts b/public/app/features/templating/variable_srv.ts index d2efdeb971e..b7013d517f4 100644 --- a/public/app/features/templating/variable_srv.ts +++ b/public/app/features/templating/variable_srv.ts @@ -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); diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index 4bb183474fb..81cffd18364 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -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}); } } } diff --git a/public/test/specs/templateSrv-specs.js b/public/test/specs/templateSrv-specs.js deleted file mode 100644 index 3dac01fbdf2..00000000000 --- a/public/test/specs/templateSrv-specs.js +++ /dev/null @@ -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('$test'); - }); - - it('should insert html anywhere in string', function() { - var result = _templateSrv.highlightVariablesAsHtml('this $test ok'); - expect(result).to.be('this $test 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'); - }); - }); - - }); - -});