mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
[Tech]: Start migrating to Jest for tests (#9610)
* tech: investigating karma + jest mix * tech: migrating tests to jest * tech: moved anoter test file to jest * test: migrated two more test files to jest * test: updated readme and made test fail to verify that it causes CI build failure * tech: added code coverage for jest tests * tech: testing codecov coverage * tech: migrated more tests * tech: migrated template srv to typescript and the tests to jest * tech: minor build fix * tech: build fixes * build: another attempt at fixing go test with coverage
This commit is contained in:
@@ -15,7 +15,6 @@ define([
|
||||
'./unsavedChangesSrv',
|
||||
'./unsaved_changes_modal',
|
||||
'./timepicker/timepicker',
|
||||
'./graphiteImportCtrl',
|
||||
'./impression_store',
|
||||
'./upload',
|
||||
'./import/dash_import',
|
||||
|
||||
@@ -11,6 +11,8 @@ define([
|
||||
function (angular, moment, _, $, kbn, dateMath, impressionStore) {
|
||||
'use strict';
|
||||
|
||||
kbn = kbn.default;
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.service('dashboardLoaderSrv', function(backendSrv,
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'app/core/utils/kbn'
|
||||
],
|
||||
function (angular, _, kbn) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('GraphiteImportCtrl', function($scope, datasourceSrv, dashboardSrv, $location) {
|
||||
$scope.options = {};
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.datasources = [];
|
||||
_.each(datasourceSrv.getAll(), function(ds) {
|
||||
if (ds.type === 'graphite') {
|
||||
$scope.options.sourceName = ds.name;
|
||||
$scope.datasources.push(ds.name);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.listAll = function() {
|
||||
datasourceSrv.get($scope.options.sourceName).then(function(datasource) {
|
||||
$scope.datasource = datasource;
|
||||
$scope.datasource.listDashboards('').then(function(results) {
|
||||
$scope.dashboards = results;
|
||||
}, function(err) {
|
||||
var message = err.message || err.statusText || 'Error';
|
||||
$scope.appEvent('alert-error', ['Failed to load dashboard list from graphite', message]);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.import = function(dashName) {
|
||||
$scope.datasource.loadDashboard(dashName).then(function(results) {
|
||||
if (!results.data || !results.data.state) {
|
||||
throw { message: 'no dashboard state received from graphite' };
|
||||
}
|
||||
|
||||
graphiteToGrafanaTranslator(results.data.state, $scope.datasource.name);
|
||||
}, function(err) {
|
||||
var message = err.message || err.statusText || 'Error';
|
||||
$scope.appEvent('alert-error', ['Failed to load dashboard from graphite', message]);
|
||||
});
|
||||
};
|
||||
|
||||
function graphiteToGrafanaTranslator(state, datasource) {
|
||||
var graphsPerRow = 2;
|
||||
var rowHeight = 300;
|
||||
var rowTemplate;
|
||||
var currentRow;
|
||||
var panel;
|
||||
|
||||
rowTemplate = {
|
||||
title: '',
|
||||
panels: [],
|
||||
height: rowHeight
|
||||
};
|
||||
|
||||
currentRow = angular.copy(rowTemplate);
|
||||
|
||||
var newDashboard = dashboardSrv.create({});
|
||||
newDashboard.rows = [];
|
||||
newDashboard.title = state.name;
|
||||
newDashboard.rows.push(currentRow);
|
||||
|
||||
_.each(state.graphs, function(graph, index) {
|
||||
if (currentRow.panels.length === graphsPerRow) {
|
||||
currentRow = angular.copy(rowTemplate);
|
||||
newDashboard.rows.push(currentRow);
|
||||
}
|
||||
|
||||
panel = {
|
||||
type: 'graph',
|
||||
span: 12 / graphsPerRow,
|
||||
title: graph[1].title,
|
||||
targets: [],
|
||||
datasource: datasource,
|
||||
id: index + 1
|
||||
};
|
||||
|
||||
_.each(graph[1].target, function(target) {
|
||||
panel.targets.push({ target: target });
|
||||
});
|
||||
|
||||
currentRow.panels.push(panel);
|
||||
});
|
||||
|
||||
window.grafanaImportDashboard = newDashboard;
|
||||
$location.path('/dashboard-import/' + kbn.slugifyForUrl(newDashboard.title));
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,8 @@ define([
|
||||
function (angular, _, kbn) {
|
||||
'use strict';
|
||||
|
||||
kbn = kbn.default;
|
||||
|
||||
angular
|
||||
.module('grafana.services')
|
||||
.service('linkSrv', function(templateSrv, timeSrv) {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import _ from 'lodash';
|
||||
import {Variable, assignModelProperties, variableTypes} from './variable';
|
||||
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import './templateSrv';
|
||||
import './editor_ctrl';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
import {VariableSrv} from './variable_srv';
|
||||
import {IntervalVariable} from './interval_variable';
|
||||
import {QueryVariable} from './query_variable';
|
||||
import {DatasourceVariable} from './datasource_variable';
|
||||
import {CustomVariable} from './custom_variable';
|
||||
import {ConstantVariable} from './constant_variable';
|
||||
import {AdhocVariable} from './adhoc_variable';
|
||||
import { TemplateSrv } from './template_srv';
|
||||
import { VariableSrv } from './variable_srv';
|
||||
import { IntervalVariable } from './interval_variable';
|
||||
import { QueryVariable } from './query_variable';
|
||||
import { DatasourceVariable } from './datasource_variable';
|
||||
import { CustomVariable } from './custom_variable';
|
||||
import { ConstantVariable } from './constant_variable';
|
||||
import { AdhocVariable } from './adhoc_variable';
|
||||
|
||||
coreModule.service('templateSrv', TemplateSrv);
|
||||
|
||||
export {
|
||||
TemplateSrv,
|
||||
VariableSrv,
|
||||
IntervalVariable,
|
||||
QueryVariable,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import _ from 'lodash';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import {Variable, containsVariable, assignModelProperties, variableTypes} from './variable';
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import {describe, it, expect} from 'test/lib/common';
|
||||
|
||||
import {AdhocVariable} from '../adhoc_variable';
|
||||
|
||||
describe('AdhocVariable', function() {
|
||||
@@ -15,7 +13,7 @@ describe('AdhocVariable', function() {
|
||||
]
|
||||
});
|
||||
var urlValue = variable.getValueForUrl();
|
||||
expect(urlValue).to.eql(["key1|=|value1", "key2|!=|value2", "key3|=|value3a__gfp__value3b__gfp__value3c"]);
|
||||
expect(urlValue).toMatchObject(["key1|=|value1", "key2|!=|value2", "key3|=|value3a__gfp__value3b__gfp__value3c"]);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -26,17 +24,17 @@ describe('AdhocVariable', function() {
|
||||
var variable = new AdhocVariable({});
|
||||
variable.setValueFromUrl(["key1|=|value1", "key2|!=|value2", "key3|=|value3a__gfp__value3b__gfp__value3c"]);
|
||||
|
||||
expect(variable.filters[0].key).to.be('key1');
|
||||
expect(variable.filters[0].operator).to.be('=');
|
||||
expect(variable.filters[0].value).to.be('value1');
|
||||
expect(variable.filters[0].key).toBe('key1');
|
||||
expect(variable.filters[0].operator).toBe('=');
|
||||
expect(variable.filters[0].value).toBe('value1');
|
||||
|
||||
expect(variable.filters[1].key).to.be('key2');
|
||||
expect(variable.filters[1].operator).to.be('!=');
|
||||
expect(variable.filters[1].value).to.be('value2');
|
||||
expect(variable.filters[1].key).toBe('key2');
|
||||
expect(variable.filters[1].operator).toBe('!=');
|
||||
expect(variable.filters[1].value).toBe('value2');
|
||||
|
||||
expect(variable.filters[2].key).to.be('key3');
|
||||
expect(variable.filters[2].operator).to.be('=');
|
||||
expect(variable.filters[2].value).to.be('value3a|value3b|value3c');
|
||||
expect(variable.filters[2].key).toBe('key3');
|
||||
expect(variable.filters[2].operator).toBe('=');
|
||||
expect(variable.filters[2].value).toBe('value3a|value3b|value3c');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,5 +1,3 @@
|
||||
import {describe, it, expect} from 'test/lib/common';
|
||||
|
||||
import {QueryVariable} from '../query_variable';
|
||||
|
||||
describe('QueryVariable', () => {
|
||||
@@ -8,14 +6,14 @@ describe('QueryVariable', () => {
|
||||
|
||||
it('should set defaults', () => {
|
||||
var variable = new QueryVariable({}, null, null, null, null);
|
||||
expect(variable.datasource).to.be(null);
|
||||
expect(variable.refresh).to.be(0);
|
||||
expect(variable.sort).to.be(0);
|
||||
expect(variable.name).to.be('');
|
||||
expect(variable.hide).to.be(0);
|
||||
expect(variable.options.length).to.be(0);
|
||||
expect(variable.multi).to.be(false);
|
||||
expect(variable.includeAll).to.be(false);
|
||||
expect(variable.datasource).toBe(null);
|
||||
expect(variable.refresh).toBe(0);
|
||||
expect(variable.sort).toBe(0);
|
||||
expect(variable.name).toBe('');
|
||||
expect(variable.hide).toBe(0);
|
||||
expect(variable.options.length).toBe(0);
|
||||
expect(variable.multi).toBe(false);
|
||||
expect(variable.includeAll).toBe(false);
|
||||
});
|
||||
|
||||
it('get model should copy changes back to model', () => {
|
||||
@@ -26,11 +24,11 @@ describe('QueryVariable', () => {
|
||||
variable.sort = 50;
|
||||
|
||||
var model = variable.getSaveModel();
|
||||
expect(model.options.length).to.be(1);
|
||||
expect(model.options[0].text).to.be('test');
|
||||
expect(model.datasource).to.be('google');
|
||||
expect(model.regex).to.be('asd');
|
||||
expect(model.sort).to.be(50);
|
||||
expect(model.options.length).toBe(1);
|
||||
expect(model.options[0].text).toBe('test');
|
||||
expect(model.datasource).toBe('google');
|
||||
expect(model.regex).toBe('asd');
|
||||
expect(model.sort).toBe(50);
|
||||
});
|
||||
|
||||
it('if refresh != 0 then remove options in presisted mode', () => {
|
||||
@@ -39,7 +37,7 @@ describe('QueryVariable', () => {
|
||||
variable.refresh = 1;
|
||||
|
||||
var model = variable.getSaveModel();
|
||||
expect(model.options.length).to.be(0);
|
||||
expect(model.options.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -67,14 +65,14 @@ describe('QueryVariable', () => {
|
||||
it('should return in same order', () => {
|
||||
var i = 0;
|
||||
|
||||
expect(result.length).to.be(11);
|
||||
expect(result[i++].text).to.be('');
|
||||
expect(result[i++].text).to.be('0');
|
||||
expect(result[i++].text).to.be('1');
|
||||
expect(result[i++].text).to.be('3');
|
||||
expect(result[i++].text).to.be('4');
|
||||
expect(result[i++].text).to.be('5');
|
||||
expect(result[i++].text).to.be('6');
|
||||
expect(result.length).toBe(11);
|
||||
expect(result[i++].text).toBe('');
|
||||
expect(result[i++].text).toBe('0');
|
||||
expect(result[i++].text).toBe('1');
|
||||
expect(result[i++].text).toBe('3');
|
||||
expect(result[i++].text).toBe('4');
|
||||
expect(result[i++].text).toBe('5');
|
||||
expect(result[i++].text).toBe('6');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,28 +1,11 @@
|
||||
import {describe, beforeEach, it, expect, angularMocks} from 'test/lib/common';
|
||||
|
||||
import '../all';
|
||||
import {Emitter} from 'app/core/core';
|
||||
import { TemplateSrv } from '../template_srv';
|
||||
|
||||
describe('templateSrv', function() {
|
||||
var _templateSrv, _variableSrv;
|
||||
|
||||
beforeEach(angularMocks.module('grafana.core'));
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
beforeEach(angularMocks.module($provide => {
|
||||
$provide.value('timeSrv', {});
|
||||
$provide.value('datasourceSrv', {});
|
||||
}));
|
||||
|
||||
beforeEach(angularMocks.inject(function(variableSrv, templateSrv) {
|
||||
_templateSrv = templateSrv;
|
||||
_variableSrv = variableSrv;
|
||||
}));
|
||||
var _templateSrv;
|
||||
|
||||
function initTemplateSrv(variables) {
|
||||
_variableSrv.init({
|
||||
templating: {list: variables},
|
||||
events: new Emitter(),
|
||||
});
|
||||
_templateSrv = new TemplateSrv();
|
||||
_templateSrv.init(variables);
|
||||
}
|
||||
|
||||
describe('init', function() {
|
||||
@@ -32,7 +15,7 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should initialize template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.oogle.filters');
|
||||
expect(target).toBe('this.oogle.filters');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,12 +26,12 @@ describe('templateSrv', function() {
|
||||
|
||||
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');
|
||||
expect(target).toBe('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');
|
||||
expect(target).toBe('this.asd.filters');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,17 +46,17 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should return filters if datasourceName match', function() {
|
||||
var filters = _templateSrv.getAdhocFilters('oogle');
|
||||
expect(filters).to.eql([1]);
|
||||
expect(filters).toMatchObject([1]);
|
||||
});
|
||||
|
||||
it('should return empty array if datasourceName does not match', function() {
|
||||
var filters = _templateSrv.getAdhocFilters('oogleasdasd');
|
||||
expect(filters).to.eql([]);
|
||||
expect(filters).toMatchObject([]);
|
||||
});
|
||||
|
||||
it('should return filters when datasourceName match via data source variable', function() {
|
||||
var filters = _templateSrv.getAdhocFilters('logstash');
|
||||
expect(filters).to.eql([2]);
|
||||
expect(filters).toMatchObject([2]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -84,17 +67,17 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should replace $test with globbed value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.{value1,value2}.filters');
|
||||
expect(target).toBe('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');
|
||||
expect(target).toBe('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');
|
||||
expect(target).toBe('this=value1|value2');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -112,7 +95,7 @@ describe('templateSrv', function() {
|
||||
|
||||
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');
|
||||
expect(target).toBe('this.{value1,value2}.filters');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -131,12 +114,12 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should replace $test with formatted all value', function() {
|
||||
var target = _templateSrv.replace('this.$test.filters', {}, 'glob');
|
||||
expect(target).to.be('this.*.filters');
|
||||
expect(target).toBe('this.*.filters');
|
||||
});
|
||||
|
||||
it('should not escape custom all value', function() {
|
||||
var target = _templateSrv.replace('this.$test', {}, 'regex');
|
||||
expect(target).to.be('this.*');
|
||||
expect(target).toBe('this.*');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -144,49 +127,49 @@ describe('templateSrv', 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");
|
||||
expect(target).toBe("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');
|
||||
expect(result).toBe('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}');
|
||||
expect(result).toBe('{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")');
|
||||
expect(result).toBe('("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)');
|
||||
expect(result).toBe('(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');
|
||||
expect(result).toBe('test|test2');
|
||||
});
|
||||
|
||||
it('multi value and distributed should render distributed string', function() {
|
||||
var result = _templateSrv.formatValue(['test','test2'], 'distributed', { name: 'build' });
|
||||
expect(result).to.be('test,build=test2');
|
||||
expect(result).toBe('test,build=test2');
|
||||
});
|
||||
|
||||
it('multi value and distributed should render when not string', function() {
|
||||
var result = _templateSrv.formatValue(['test'], 'distributed', { name: 'build' });
|
||||
expect(result).to.be('test');
|
||||
expect(result).toBe('test');
|
||||
});
|
||||
|
||||
it('slash should be properly escaped in regex format', function() {
|
||||
var result = _templateSrv.formatValue('Gi3/14', 'regex');
|
||||
expect(result).to.be('Gi3\\/14');
|
||||
expect(result).toBe('Gi3\\/14');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -198,7 +181,7 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should return true if exists', function() {
|
||||
var result = _templateSrv.variableExists('$test');
|
||||
expect(result).to.be(true);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -209,17 +192,17 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should insert html', function() {
|
||||
var result = _templateSrv.highlightVariablesAsHtml('$test');
|
||||
expect(result).to.be('<span class="template-variable">$test</span>');
|
||||
expect(result).toBe('<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');
|
||||
expect(result).toBe('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');
|
||||
expect(result).toBe('this $google ok');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -230,19 +213,28 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should set current value and update template data', function() {
|
||||
var target = _templateSrv.replace('this.[[test]].filters');
|
||||
expect(target).to.be('this.muuuu.filters');
|
||||
expect(target).toBe('this.muuuu.filters');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fillVariableValuesForUrl with multi value', function() {
|
||||
beforeEach(function() {
|
||||
initTemplateSrv([{type: 'query', name: 'test', current: { value: ['val1', 'val2'] }}]);
|
||||
initTemplateSrv([
|
||||
{
|
||||
type: 'query',
|
||||
name: 'test',
|
||||
current: { value: ['val1', 'val2'] },
|
||||
getValueForUrl: function() {
|
||||
return this.current.value;
|
||||
}
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should set multiple url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params);
|
||||
expect(params['var-test']).to.eql(['val1', 'val2']);
|
||||
expect(params['var-test']).toMatchObject(['val1', 'val2']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -254,7 +246,7 @@ describe('templateSrv', function() {
|
||||
it('should set scoped value as url params', function() {
|
||||
var params = {};
|
||||
_templateSrv.fillVariableValuesForUrl(params, {'test': {value: 'val1'}});
|
||||
expect(params['var-test']).to.eql('val1');
|
||||
expect(params['var-test']).toBe('val1');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -270,7 +262,7 @@ describe('templateSrv', function() {
|
||||
|
||||
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');
|
||||
expect(target).toBe('Server: All, period: 13m');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -281,7 +273,7 @@ describe('templateSrv', function() {
|
||||
|
||||
it('should replace $__interval_ms with interval milliseconds', function() {
|
||||
var target = _templateSrv.replace('10 * $__interval_ms', {"__interval_ms": {text: "100", value: "100"}});
|
||||
expect(target).to.be('10 * 100');
|
||||
expect(target).toBe('10 * 100');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,253 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'app/core/utils/kbn',
|
||||
],
|
||||
function (angular, _, kbn) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
|
||||
module.service('templateSrv', function() {
|
||||
var self = this;
|
||||
|
||||
this._regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
|
||||
this._index = {};
|
||||
this._texts = {};
|
||||
this._grafanaVariables = {};
|
||||
|
||||
// default built ins
|
||||
this._builtIns = {};
|
||||
this._builtIns['__interval'] = {text: '1s', value: '1s'};
|
||||
this._builtIns['__interval_ms'] = {text: '100', value: '100'};
|
||||
|
||||
this.init = function(variables) {
|
||||
this.variables = variables;
|
||||
this.updateTemplateData();
|
||||
};
|
||||
|
||||
this.updateTemplateData = function() {
|
||||
this._index = {};
|
||||
this._filters = {};
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
var variable = this.variables[i];
|
||||
|
||||
if (!variable.current || !variable.current.isNone && !variable.current.value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this._index[variable.name] = variable;
|
||||
}
|
||||
};
|
||||
|
||||
this.variableInitialized = function(variable) {
|
||||
this._index[variable.name] = variable;
|
||||
};
|
||||
|
||||
this.getAdhocFilters = function(datasourceName) {
|
||||
var filters = [];
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
var variable = this.variables[i];
|
||||
if (variable.type !== 'adhoc') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (variable.datasource === datasourceName) {
|
||||
filters = filters.concat(variable.filters);
|
||||
}
|
||||
|
||||
if (variable.datasource.indexOf('$') === 0) {
|
||||
if (this.replace(variable.datasource) === datasourceName) {
|
||||
filters = filters.concat(variable.filters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filters;
|
||||
};
|
||||
|
||||
function luceneEscape(value) {
|
||||
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
|
||||
}
|
||||
|
||||
this.luceneFormat = function(value) {
|
||||
if (typeof value === 'string') {
|
||||
return luceneEscape(value);
|
||||
}
|
||||
var quotedValues = _.map(value, function(val) {
|
||||
return '\"' + luceneEscape(val) + '\"';
|
||||
});
|
||||
return '(' + quotedValues.join(' OR ') + ')';
|
||||
};
|
||||
|
||||
this.formatValue = function(value, format, variable) {
|
||||
// for some scopedVars there is no variable
|
||||
variable = variable || {};
|
||||
|
||||
if (typeof format === 'function') {
|
||||
return format(value, variable, this.formatValue);
|
||||
}
|
||||
|
||||
switch(format) {
|
||||
case "regex": {
|
||||
if (typeof value === 'string') {
|
||||
return kbn.regexEscape(value);
|
||||
}
|
||||
|
||||
var escapedValues = _.map(value, kbn.regexEscape);
|
||||
return '(' + escapedValues.join('|') + ')';
|
||||
}
|
||||
case "lucene": {
|
||||
return this.luceneFormat(value, format, variable);
|
||||
}
|
||||
case "pipe": {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return value.join('|');
|
||||
}
|
||||
case "distributed": {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return this.distributeVariable(value, variable.name);
|
||||
}
|
||||
default: {
|
||||
if (_.isArray(value)) {
|
||||
return '{' + value.join(',') + '}';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.setGrafanaVariable = function (name, value) {
|
||||
this._grafanaVariables[name] = value;
|
||||
};
|
||||
|
||||
this.getVariableName = function(expression) {
|
||||
this._regex.lastIndex = 0;
|
||||
var match = this._regex.exec(expression);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return match[1] || match[2];
|
||||
};
|
||||
|
||||
this.variableExists = function(expression) {
|
||||
var name = this.getVariableName(expression);
|
||||
return name && (self._index[name] !== void 0);
|
||||
};
|
||||
|
||||
this.highlightVariablesAsHtml = function(str) {
|
||||
if (!str || !_.isString(str)) { return str; }
|
||||
|
||||
str = _.escape(str);
|
||||
this._regex.lastIndex = 0;
|
||||
return str.replace(this._regex, function(match, g1, g2) {
|
||||
if (self._index[g1 || g2] || self._builtIns[g1 || g2]) {
|
||||
return '<span class="template-variable">' + match + '</span>';
|
||||
}
|
||||
return match;
|
||||
});
|
||||
};
|
||||
|
||||
this.getAllValue = function(variable) {
|
||||
if (variable.allValue) {
|
||||
return variable.allValue;
|
||||
}
|
||||
var values = [];
|
||||
for (var i = 1; i < variable.options.length; i++) {
|
||||
values.push(variable.options[i].value);
|
||||
}
|
||||
return values;
|
||||
};
|
||||
|
||||
this.replace = function(target, scopedVars, format) {
|
||||
if (!target) { return target; }
|
||||
|
||||
var variable, systemValue, value;
|
||||
this._regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this._regex, function(match, g1, g2) {
|
||||
variable = self._index[g1 || g2];
|
||||
|
||||
if (scopedVars) {
|
||||
value = scopedVars[g1 || g2];
|
||||
if (value) {
|
||||
return self.formatValue(value.value, format, variable);
|
||||
}
|
||||
}
|
||||
|
||||
if (!variable) {
|
||||
return match;
|
||||
}
|
||||
|
||||
systemValue = self._grafanaVariables[variable.current.value];
|
||||
if (systemValue) {
|
||||
return self.formatValue(systemValue, format, variable);
|
||||
}
|
||||
|
||||
value = variable.current.value;
|
||||
if (self.isAllValue(value)) {
|
||||
value = self.getAllValue(variable);
|
||||
// skip formating of custom all values
|
||||
if (variable.allValue) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
var res = self.formatValue(value, format, variable);
|
||||
return res;
|
||||
});
|
||||
};
|
||||
|
||||
this.isAllValue = function(value) {
|
||||
return value === '$__all' || Array.isArray(value) && value[0] === '$__all';
|
||||
};
|
||||
|
||||
this.replaceWithText = function(target, scopedVars) {
|
||||
if (!target) { return target; }
|
||||
|
||||
var variable;
|
||||
this._regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this._regex, function(match, g1, g2) {
|
||||
if (scopedVars) {
|
||||
var option = scopedVars[g1 || g2];
|
||||
if (option) { return option.text; }
|
||||
}
|
||||
|
||||
variable = self._index[g1 || g2];
|
||||
if (!variable) { return match; }
|
||||
|
||||
return self._grafanaVariables[variable.current.value] || variable.current.text;
|
||||
});
|
||||
};
|
||||
|
||||
this.fillVariableValuesForUrl = function(params, scopedVars) {
|
||||
_.each(this.variables, function(variable) {
|
||||
if (scopedVars && scopedVars[variable.name] !== void 0) {
|
||||
params['var-' + variable.name] = scopedVars[variable.name].value;
|
||||
} else {
|
||||
params['var-' + variable.name] = variable.getValueForUrl();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
this.distributeVariable = function(value, variable) {
|
||||
value = _.map(value, function(val, index) {
|
||||
if (index !== 0) {
|
||||
return variable + "=" + val;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
});
|
||||
return value.join(',');
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
244
public/app/features/templating/template_srv.ts
Normal file
244
public/app/features/templating/template_srv.ts
Normal file
@@ -0,0 +1,244 @@
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import _ from 'lodash';
|
||||
|
||||
function luceneEscape(value) {
|
||||
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
|
||||
}
|
||||
|
||||
export class TemplateSrv {
|
||||
variables: any[];
|
||||
|
||||
private regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
|
||||
private index = {};
|
||||
private grafanaVariables = {};
|
||||
private builtIns = {};
|
||||
private filters = {};
|
||||
|
||||
constructor() {
|
||||
this.builtIns['__interval'] = {text: '1s', value: '1s'};
|
||||
this.builtIns['__interval_ms'] = {text: '100', value: '100'};
|
||||
}
|
||||
|
||||
init(variables) {
|
||||
this.variables = variables;
|
||||
this.updateTemplateData();
|
||||
}
|
||||
|
||||
updateTemplateData() {
|
||||
this.index = {};
|
||||
this.filters = {};
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
var variable = this.variables[i];
|
||||
|
||||
if (!variable.current || !variable.current.isNone && !variable.current.value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.index[variable.name] = variable;
|
||||
}
|
||||
}
|
||||
|
||||
variableInitialized(variable) {
|
||||
this.index[variable.name] = variable;
|
||||
}
|
||||
|
||||
getAdhocFilters(datasourceName) {
|
||||
var filters = [];
|
||||
|
||||
for (var i = 0; i < this.variables.length; i++) {
|
||||
var variable = this.variables[i];
|
||||
if (variable.type !== 'adhoc') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (variable.datasource === datasourceName) {
|
||||
filters = filters.concat(variable.filters);
|
||||
}
|
||||
|
||||
if (variable.datasource.indexOf('$') === 0) {
|
||||
if (this.replace(variable.datasource) === datasourceName) {
|
||||
filters = filters.concat(variable.filters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
luceneFormat(value) {
|
||||
if (typeof value === 'string') {
|
||||
return luceneEscape(value);
|
||||
}
|
||||
var quotedValues = _.map(value, function(val) {
|
||||
return '\"' + luceneEscape(val) + '\"';
|
||||
});
|
||||
return '(' + quotedValues.join(' OR ') + ')';
|
||||
}
|
||||
|
||||
formatValue(value, format, variable) {
|
||||
// for some scopedVars there is no variable
|
||||
variable = variable || {};
|
||||
|
||||
if (typeof format === 'function') {
|
||||
return format(value, variable, this.formatValue);
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case "regex": {
|
||||
if (typeof value === 'string') {
|
||||
return kbn.regexEscape(value);
|
||||
}
|
||||
|
||||
var escapedValues = _.map(value, kbn.regexEscape);
|
||||
return '(' + escapedValues.join('|') + ')';
|
||||
}
|
||||
case "lucene": {
|
||||
return this.luceneFormat(value);
|
||||
}
|
||||
case "pipe": {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return value.join('|');
|
||||
}
|
||||
case "distributed": {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return this.distributeVariable(value, variable.name);
|
||||
}
|
||||
default: {
|
||||
if (_.isArray(value)) {
|
||||
return '{' + value.join(',') + '}';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setGrafanaVariable(name, value) {
|
||||
this.grafanaVariables[name] = value;
|
||||
}
|
||||
|
||||
getVariableName(expression) {
|
||||
this.regex.lastIndex = 0;
|
||||
var match = this.regex.exec(expression);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return match[1] || match[2];
|
||||
}
|
||||
|
||||
variableExists(expression) {
|
||||
var name = this.getVariableName(expression);
|
||||
return name && (this.index[name] !== void 0);
|
||||
}
|
||||
|
||||
highlightVariablesAsHtml(str) {
|
||||
if (!str || !_.isString(str)) { return str; }
|
||||
|
||||
str = _.escape(str);
|
||||
this.regex.lastIndex = 0;
|
||||
return str.replace(this.regex, (match, g1, g2) => {
|
||||
if (this.index[g1 || g2] || this.builtIns[g1 || g2]) {
|
||||
return '<span class="template-variable">' + match + '</span>';
|
||||
}
|
||||
return match;
|
||||
});
|
||||
}
|
||||
|
||||
getAllValue(variable) {
|
||||
if (variable.allValue) {
|
||||
return variable.allValue;
|
||||
}
|
||||
var values = [];
|
||||
for (var i = 1; i < variable.options.length; i++) {
|
||||
values.push(variable.options[i].value);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
replace(target, scopedVars?, format?) {
|
||||
if (!target) { return target; }
|
||||
|
||||
var variable, systemValue, value;
|
||||
this.regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this.regex, (match, g1, g2) => {
|
||||
variable = this.index[g1 || g2];
|
||||
|
||||
if (scopedVars) {
|
||||
value = scopedVars[g1 || g2];
|
||||
if (value) {
|
||||
return this.formatValue(value.value, format, variable);
|
||||
}
|
||||
}
|
||||
|
||||
if (!variable) {
|
||||
return match;
|
||||
}
|
||||
|
||||
systemValue = this.grafanaVariables[variable.current.value];
|
||||
if (systemValue) {
|
||||
return this.formatValue(systemValue, format, variable);
|
||||
}
|
||||
|
||||
value = variable.current.value;
|
||||
if (this.isAllValue(value)) {
|
||||
value = this.getAllValue(variable);
|
||||
// skip formating of custom all values
|
||||
if (variable.allValue) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
var res = this.formatValue(value, format, variable);
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
isAllValue(value) {
|
||||
return value === '$__all' || Array.isArray(value) && value[0] === '$__all';
|
||||
}
|
||||
|
||||
replaceWithText(target, scopedVars) {
|
||||
if (!target) { return target; }
|
||||
|
||||
var variable;
|
||||
this.regex.lastIndex = 0;
|
||||
|
||||
return target.replace(this.regex, (match, g1, g2) => {
|
||||
if (scopedVars) {
|
||||
var option = scopedVars[g1 || g2];
|
||||
if (option) { return option.text; }
|
||||
}
|
||||
|
||||
variable = this.index[g1 || g2];
|
||||
if (!variable) { return match; }
|
||||
|
||||
return this.grafanaVariables[variable.current.value] || variable.current.text;
|
||||
});
|
||||
}
|
||||
|
||||
fillVariableValuesForUrl(params, scopedVars) {
|
||||
_.each(this.variables, function(variable) {
|
||||
if (scopedVars && scopedVars[variable.name] !== void 0) {
|
||||
params['var-' + variable.name] = scopedVars[variable.name].value;
|
||||
} else {
|
||||
params['var-' + variable.name] = variable.getValueForUrl();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
distributeVariable(value, variable) {
|
||||
value = _.map(value, function(val, index) {
|
||||
if (index !== 0) {
|
||||
return variable + "=" + val;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
});
|
||||
return value.join(',');
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import {assignModelProperties} from 'app/core/core';
|
||||
import {assignModelProperties} from 'app/core/utils/model_utils';
|
||||
|
||||
export interface Variable {
|
||||
setValue(option);
|
||||
|
||||
Reference in New Issue
Block a user