From 7e434fc0195244a795a642e351e8c57adb632918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 28 Sep 2015 15:23:53 +0200 Subject: [PATCH] refactor: moved graphite specs into plugins directory --- karma.conf.js | 1 + ...ddGraphiteFunc.js => add_graphite_func.js} | 0 .../plugins/datasource/graphite/datasource.js | 6 +- .../{funcEditor.js => func_editor.js} | 0 .../graphite/{queryCtrl.js => query_ctrl.js} | 0 .../graphite/specs/datasource_specs.ts | 120 ++++++++++++ .../datasource/graphite/specs/gfunc_specs.ts | 127 +++++++++++++ .../graphite/specs/query_ctrl_specs.ts | 178 +++++++++++++++++ public/test/lib/common.ts | 7 +- public/test/specs/gfunc-specs.js | 130 ------------- public/test/specs/graphiteDatasource-specs.js | 122 ------------ public/test/specs/graphiteTargetCtrl-specs.js | 179 ------------------ public/test/test-main.js | 2 +- 13 files changed, 436 insertions(+), 436 deletions(-) rename public/app/plugins/datasource/graphite/{addGraphiteFunc.js => add_graphite_func.js} (100%) rename public/app/plugins/datasource/graphite/{funcEditor.js => func_editor.js} (100%) rename public/app/plugins/datasource/graphite/{queryCtrl.js => query_ctrl.js} (100%) create mode 100644 public/app/plugins/datasource/graphite/specs/datasource_specs.ts create mode 100644 public/app/plugins/datasource/graphite/specs/gfunc_specs.ts create mode 100644 public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts delete mode 100644 public/test/specs/gfunc-specs.js delete mode 100644 public/test/specs/graphiteDatasource-specs.js delete mode 100644 public/test/specs/graphiteTargetCtrl-specs.js diff --git a/karma.conf.js b/karma.conf.js index 569cf845b16..f05b7dcc61a 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -25,6 +25,7 @@ module.exports = function(config) { browsers: ['PhantomJS'], captureTimeout: 60000, singleRun: true, + autoWatchBatchDelay: 1000, }); diff --git a/public/app/plugins/datasource/graphite/addGraphiteFunc.js b/public/app/plugins/datasource/graphite/add_graphite_func.js similarity index 100% rename from public/app/plugins/datasource/graphite/addGraphiteFunc.js rename to public/app/plugins/datasource/graphite/add_graphite_func.js diff --git a/public/app/plugins/datasource/graphite/datasource.js b/public/app/plugins/datasource/graphite/datasource.js index d51f9a93280..553a11c2350 100644 --- a/public/app/plugins/datasource/graphite/datasource.js +++ b/public/app/plugins/datasource/graphite/datasource.js @@ -5,9 +5,9 @@ define([ 'config', 'app/core/utils/datemath', './directives', - './queryCtrl', - './funcEditor', - './addGraphiteFunc', + './query_ctrl', + './func_editor', + './add_graphite_func', ], function (angular, _, $, config, dateMath) { 'use strict'; diff --git a/public/app/plugins/datasource/graphite/funcEditor.js b/public/app/plugins/datasource/graphite/func_editor.js similarity index 100% rename from public/app/plugins/datasource/graphite/funcEditor.js rename to public/app/plugins/datasource/graphite/func_editor.js diff --git a/public/app/plugins/datasource/graphite/queryCtrl.js b/public/app/plugins/datasource/graphite/query_ctrl.js similarity index 100% rename from public/app/plugins/datasource/graphite/queryCtrl.js rename to public/app/plugins/datasource/graphite/query_ctrl.js diff --git a/public/app/plugins/datasource/graphite/specs/datasource_specs.ts b/public/app/plugins/datasource/graphite/specs/datasource_specs.ts new file mode 100644 index 00000000000..8ba7e35b773 --- /dev/null +++ b/public/app/plugins/datasource/graphite/specs/datasource_specs.ts @@ -0,0 +1,120 @@ +/// +/// + +import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; +declare var helpers: any; + +describe('graphiteDatasource', function() { + var ctx = new helpers.ServiceTestContext(); + + beforeEach(angularMocks.module('grafana.services')); + beforeEach(ctx.providePhase(['backendSrv'])); + + beforeEach(ctx.createService('GraphiteDatasource')); + beforeEach(function() { + ctx.ds = new ctx.service({ url: [''] }); + }); + + describe('When querying influxdb with one target using query editor target spec', function() { + var query = { + rangeRaw: { from: 'now-1h', to: 'now' }, + targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}], + maxDataPoints: 500, + }; + + var results; + var requestOptions; + + beforeEach(function() { + ctx.backendSrv.datasourceRequest = function(options) { + requestOptions = options; + return ctx.$q.when({data: [{ target: 'prod1.count', datapoints: [[10, 1], [12,1]] }]}); + }; + + ctx.ds.query(query).then(function(data) { results = data; }); + ctx.$rootScope.$apply(); + }); + + it('should generate the correct query', function() { + expect(requestOptions.url).to.be('/render'); + }); + + it('should query correctly', function() { + var params = requestOptions.data.split('&'); + expect(params).to.contain('target=prod1.count'); + expect(params).to.contain('target=prod2.count'); + expect(params).to.contain('from=-1h'); + expect(params).to.contain('until=now'); + }); + + it('should exclude undefined params', function() { + var params = requestOptions.data.split('&'); + expect(params).to.not.contain('cacheTimeout=undefined'); + }); + + it('should return series list', function() { + expect(results.data.length).to.be(1); + expect(results.data[0].target).to.be('prod1.count'); + }); + + it('should convert to millisecond resolution', function() { + expect(results.data[0].datapoints[0][0]).to.be(10); + }); + + }); + + describe('building graphite params', function() { + + it('should uri escape targets', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: 'prod1.{test,test2}'}, {target: 'prod2.count'}] + }); + expect(results).to.contain('target=prod1.%7Btest%2Ctest2%7D'); + }); + + it('should replace target placeholder', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: 'series1'}, {target: 'series2'}, {target: 'asPercent(#A,#B)'}] + }); + expect(results[2]).to.be('target=asPercent(series1%2Cseries2)'); + }); + + it('should replace target placeholder for hidden series', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: 'series1', hide: true}, {target: 'sumSeries(#A)', hide: true}, {target: 'asPercent(#A,#B)'}] + }); + expect(results[0]).to.be('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))')); + }); + + it('should replace target placeholder when nesting query references', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: 'series1'}, {target: 'sumSeries(#A)'}, {target: 'asPercent(#A,#B)'}] + }); + expect(results[2]).to.be('target=' + encodeURIComponent("asPercent(series1,sumSeries(series1))")); + }); + + it('should fix wrong minute interval parameters', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: "summarize(prod.25m.count, '25m', 'sum')" }] + }); + expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')")); + }); + + it('should fix wrong month interval parameters', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: "summarize(prod.5M.count, '5M', 'sum')" }] + }); + expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')")); + }); + + it('should ignore empty targets', function() { + var results = ctx.ds.buildGraphiteParams({ + targets: [{target: 'series1'}, {target: ''}] + }); + expect(results.length).to.be(2); + }); + + }); + +}); + diff --git a/public/app/plugins/datasource/graphite/specs/gfunc_specs.ts b/public/app/plugins/datasource/graphite/specs/gfunc_specs.ts new file mode 100644 index 00000000000..ec8c5dbe1ad --- /dev/null +++ b/public/app/plugins/datasource/graphite/specs/gfunc_specs.ts @@ -0,0 +1,127 @@ +/// + +import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'; + +declare var gfunc: any; + +describe('when creating func instance from func names', function() { + it('should return func instance', function() { + var func = gfunc.createFuncInstance('sumSeries'); + expect(func).to.be.ok(); + expect(func.def.name).to.equal('sumSeries'); + expect(func.def.params.length).to.equal(5); + expect(func.def.defaultParams.length).to.equal(1); + }); + + it('should return func instance with shortName', function() { + var func = gfunc.createFuncInstance('sum'); + expect(func).to.be.ok(); + }); + + it('should return func instance from funcDef', function() { + var func = gfunc.createFuncInstance('sum'); + var func2 = gfunc.createFuncInstance(func.def); + expect(func2).to.be.ok(); + }); + + it('func instance should have text representation', function() { + var func = gfunc.createFuncInstance('groupByNode'); + func.params[0] = 5; + func.params[1] = 'avg'; + func.updateText(); + expect(func.text).to.equal("groupByNode(5, avg)"); + }); +}); + +describe('when rendering func instance', function() { + + it('should handle single metric param', function() { + var func = gfunc.createFuncInstance('sumSeries'); + expect(func.render('hello.metric')).to.equal("sumSeries(hello.metric)"); + }); + + it('should include default params if options enable it', function() { + var func = gfunc.createFuncInstance('scaleToSeconds', { withDefaultParams: true }); + expect(func.render('hello')).to.equal("scaleToSeconds(hello, 1)"); + }); + + it('should handle int or interval params with number', function() { + var func = gfunc.createFuncInstance('movingMedian'); + func.params[0] = '5'; + expect(func.render('hello')).to.equal("movingMedian(hello, 5)"); + }); + + it('should handle int or interval params with interval string', function() { + var func = gfunc.createFuncInstance('movingMedian'); + func.params[0] = '5min'; + expect(func.render('hello')).to.equal("movingMedian(hello, '5min')"); + }); + + it('should handle metric param and int param and string param', function() { + var func = gfunc.createFuncInstance('groupByNode'); + func.params[0] = 5; + func.params[1] = 'avg'; + expect(func.render('hello.metric')).to.equal("groupByNode(hello.metric, 5, 'avg')"); + }); + + it('should handle function with no metric param', function() { + var func = gfunc.createFuncInstance('randomWalk'); + func.params[0] = 'test'; + expect(func.render(undefined)).to.equal("randomWalk('test')"); + }); + + it('should handle function multiple series params', function() { + var func = gfunc.createFuncInstance('asPercent'); + func.params[0] = '#B'; + expect(func.render('#A')).to.equal("asPercent(#A, #B)"); + }); + +}); + +describe('when requesting function categories', function() { + it('should return function categories', function() { + var catIndex = gfunc.getCategories(); + expect(catIndex.Special.length).to.be.greaterThan(8); + }); +}); + +describe('when updating func param', function() { + it('should update param value and update text representation', function() { + var func = gfunc.createFuncInstance('summarize', { withDefaultParams: true }); + func.updateParam('1h', 0); + expect(func.params[0]).to.be('1h'); + expect(func.text).to.be('summarize(1h, sum, false)'); + }); + + it('should parse numbers as float', function() { + var func = gfunc.createFuncInstance('scale'); + func.updateParam('0.001', 0); + expect(func.params[0]).to.be('0.001'); + }); +}); + +describe('when updating func param with optional second parameter', function() { + it('should update value and text', function() { + var func = gfunc.createFuncInstance('aliasByNode'); + func.updateParam('1', 0); + expect(func.params[0]).to.be('1'); + }); + + it('should slit text and put value in second param', function() { + var func = gfunc.createFuncInstance('aliasByNode'); + func.updateParam('4,-5', 0); + expect(func.params[0]).to.be('4'); + expect(func.params[1]).to.be('-5'); + expect(func.text).to.be('aliasByNode(4, -5)'); + }); + + it('should remove second param when empty string is set', function() { + var func = gfunc.createFuncInstance('aliasByNode'); + func.updateParam('4,-5', 0); + func.updateParam('', 1); + expect(func.params[0]).to.be('4'); + expect(func.params[1]).to.be(undefined); + expect(func.text).to.be('aliasByNode(4)'); + }); +}); + diff --git a/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts b/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts new file mode 100644 index 00000000000..0b12ea051e0 --- /dev/null +++ b/public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts @@ -0,0 +1,178 @@ +/// +/// +/// +/// + +import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; + +declare var gfunc: any; +declare var helpers: any; + +describe('GraphiteQueryCtrl', function() { + var ctx = new helpers.ControllerTestContext(); + + beforeEach(angularMocks.module('grafana.controllers')); + beforeEach(angularMocks.module('grafana.services')); + beforeEach(ctx.providePhase()); + beforeEach(ctx.createControllerPhase('GraphiteQueryCtrl')); + + beforeEach(function() { + ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'}; + + ctx.scope.datasource = ctx.datasource; + ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([])); + }); + + describe('init', function() { + beforeEach(function() { + ctx.scope.init(); + ctx.scope.$digest(); + }); + + it('should validate metric key exists', function() { + expect(ctx.scope.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*'); + }); + + it('should delete last segment if no metrics are found', function() { + expect(ctx.scope.segments[2].value).to.be('select metric'); + }); + + it('should parse expression and build function model', function() { + expect(ctx.scope.functions.length).to.be(2); + }); + }); + + describe('when adding function', function() { + beforeEach(function() { + ctx.scope.target.target = 'test.prod.*.count'; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}])); + ctx.scope.init(); + ctx.scope.$digest(); + + ctx.scope.$parent = { get_data: sinon.spy() }; + ctx.scope.addFunction(gfunc.getFuncDef('aliasByNode')); + }); + + it('should add function with correct node number', function() { + expect(ctx.scope.functions[0].params[0]).to.be(2); + }); + + it('should update target', function() { + expect(ctx.scope.target.target).to.be('aliasByNode(test.prod.*.count, 2)'); + }); + + it('should call get_data', function() { + expect(ctx.scope.$parent.get_data.called).to.be(true); + }); + }); + + describe('when adding function before any metric segment', function() { + beforeEach(function() { + ctx.scope.target.target = ''; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}])); + ctx.scope.init(); + ctx.scope.$digest(); + + ctx.scope.$parent = { get_data: sinon.spy() }; + ctx.scope.addFunction(gfunc.getFuncDef('asPercent')); + }); + + it('should add function and remove select metric link', function() { + expect(ctx.scope.segments.length).to.be(0); + }); + }); + + describe('when initalizing target without metric expression and only function', function() { + beforeEach(function() { + ctx.scope.target.target = 'asPercent(#A, #B)'; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); + ctx.scope.init(); + ctx.scope.$digest(); + ctx.scope.$parent = { get_data: sinon.spy() }; + }); + + it('should not add select metric segment', function() { + expect(ctx.scope.segments.length).to.be(0); + }); + + it('should add both series refs as params', function() { + expect(ctx.scope.functions[0].params.length).to.be(2); + }); + + }); + + describe('when initializing a target with single param func using variable', function() { + beforeEach(function() { + ctx.scope.target.target = 'movingAverage(prod.count, $var)'; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); + ctx.scope.init(); + ctx.scope.$digest(); + ctx.scope.$parent = { get_data: sinon.spy() }; + }); + + it('should add 2 segments', function() { + expect(ctx.scope.segments.length).to.be(2); + }); + + it('should add function param', function() { + expect(ctx.scope.functions[0].params.length).to.be(1); + }); + + }); + + describe('when initalizing target without metric expression and function with series-ref', function() { + beforeEach(function() { + ctx.scope.target.target = 'asPercent(metric.node.count, #A)'; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); + ctx.scope.init(); + ctx.scope.$digest(); + ctx.scope.$parent = { get_data: sinon.spy() }; + }); + + it('should add segments', function() { + expect(ctx.scope.segments.length).to.be(3); + }); + + it('should have correct func params', function() { + expect(ctx.scope.functions[0].params.length).to.be(1); + }); + }); + + describe('when getting altSegments and metricFindQuery retuns empty array', function() { + beforeEach(function() { + ctx.scope.target.target = 'test.count'; + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); + ctx.scope.init(); + ctx.scope.getAltSegments(1).then(function(results) { + ctx.altSegments = results; + }); + ctx.scope.$digest(); + ctx.scope.$parent = { get_data: sinon.spy() }; + }); + + it('should have no segments', function() { + expect(ctx.altSegments.length).to.be(0); + }); + + }); + + describe('targetChanged', function() { + beforeEach(function() { + ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}])); + ctx.scope.init(); + ctx.scope.$digest(); + + ctx.scope.$parent = { get_data: sinon.spy() }; + ctx.scope.target.target = ''; + ctx.scope.targetChanged(); + }); + + it('should rebuld target after expression model', function() { + expect(ctx.scope.target.target).to.be('aliasByNode(scaleToSeconds(test.prod.*, 1), 2)'); + }); + + it('should call get_data', function() { + expect(ctx.scope.$parent.get_data.called).to.be(true); + }); + }); +}); diff --git a/public/test/lib/common.ts b/public/test/lib/common.ts index 53f50301d42..523a97c2c03 100644 --- a/public/test/lib/common.ts +++ b/public/test/lib/common.ts @@ -7,10 +7,15 @@ var it = _global.it; var sinon = _global.sinon; var expect = _global.expect; +var angularMocks = { + module: _global.module, +}; + export { beforeEach, describe, it, sinon, - expect + expect, + angularMocks, } diff --git a/public/test/specs/gfunc-specs.js b/public/test/specs/gfunc-specs.js deleted file mode 100644 index 15096536de5..00000000000 --- a/public/test/specs/gfunc-specs.js +++ /dev/null @@ -1,130 +0,0 @@ -define([ - 'app/plugins/datasource/graphite/gfunc' -], function(gfunc) { - 'use strict'; - - describe('when creating func instance from func names', function() { - - it('should return func instance', function() { - var func = gfunc.createFuncInstance('sumSeries'); - expect(func).to.be.ok(); - expect(func.def.name).to.equal('sumSeries'); - expect(func.def.params.length).to.equal(5); - expect(func.def.defaultParams.length).to.equal(1); - }); - - it('should return func instance with shortName', function() { - var func = gfunc.createFuncInstance('sum'); - expect(func).to.be.ok(); - }); - - it('should return func instance from funcDef', function() { - var func = gfunc.createFuncInstance('sum'); - var func2 = gfunc.createFuncInstance(func.def); - expect(func2).to.be.ok(); - }); - - it('func instance should have text representation', function() { - var func = gfunc.createFuncInstance('groupByNode'); - func.params[0] = 5; - func.params[1] = 'avg'; - func.updateText(); - expect(func.text).to.equal("groupByNode(5, avg)"); - }); - - }); - - describe('when rendering func instance', function() { - - it('should handle single metric param', function() { - var func = gfunc.createFuncInstance('sumSeries'); - expect(func.render('hello.metric')).to.equal("sumSeries(hello.metric)"); - }); - - it('should include default params if options enable it', function() { - var func = gfunc.createFuncInstance('scaleToSeconds', { withDefaultParams: true }); - expect(func.render('hello')).to.equal("scaleToSeconds(hello, 1)"); - }); - - it('should handle int or interval params with number', function() { - var func = gfunc.createFuncInstance('movingMedian'); - func.params[0] = '5'; - expect(func.render('hello')).to.equal("movingMedian(hello, 5)"); - }); - - it('should handle int or interval params with interval string', function() { - var func = gfunc.createFuncInstance('movingMedian'); - func.params[0] = '5min'; - expect(func.render('hello')).to.equal("movingMedian(hello, '5min')"); - }); - - it('should handle metric param and int param and string param', function() { - var func = gfunc.createFuncInstance('groupByNode'); - func.params[0] = 5; - func.params[1] = 'avg'; - expect(func.render('hello.metric')).to.equal("groupByNode(hello.metric, 5, 'avg')"); - }); - - it('should handle function with no metric param', function() { - var func = gfunc.createFuncInstance('randomWalk'); - func.params[0] = 'test'; - expect(func.render(undefined)).to.equal("randomWalk('test')"); - }); - - it('should handle function multiple series params', function() { - var func = gfunc.createFuncInstance('asPercent'); - func.params[0] = '#B'; - expect(func.render('#A')).to.equal("asPercent(#A, #B)"); - }); - - }); - - describe('when requesting function categories', function() { - it('should return function categories', function() { - var catIndex = gfunc.getCategories(); - expect(catIndex.Special.length).to.be.greaterThan(8); - }); - }); - - describe('when updating func param', function() { - it('should update param value and update text representation', function() { - var func = gfunc.createFuncInstance('summarize', { withDefaultParams: true }); - func.updateParam('1h', 0); - expect(func.params[0]).to.be('1h'); - expect(func.text).to.be('summarize(1h, sum, false)'); - }); - - it('should parse numbers as float', function() { - var func = gfunc.createFuncInstance('scale'); - func.updateParam('0.001', 0); - expect(func.params[0]).to.be('0.001'); - }); - }); - - describe('when updating func param with optional second parameter', function() { - it('should update value and text', function() { - var func = gfunc.createFuncInstance('aliasByNode'); - func.updateParam('1', 0); - expect(func.params[0]).to.be('1'); - }); - - it('should slit text and put value in second param', function() { - var func = gfunc.createFuncInstance('aliasByNode'); - func.updateParam('4,-5', 0); - expect(func.params[0]).to.be('4'); - expect(func.params[1]).to.be('-5'); - expect(func.text).to.be('aliasByNode(4, -5)'); - }); - - it('should remove second param when empty string is set', function() { - var func = gfunc.createFuncInstance('aliasByNode'); - func.updateParam('4,-5', 0); - func.updateParam('', 1); - expect(func.params[0]).to.be('4'); - expect(func.params[1]).to.be(undefined); - expect(func.text).to.be('aliasByNode(4)'); - }); - }); - -}); - diff --git a/public/test/specs/graphiteDatasource-specs.js b/public/test/specs/graphiteDatasource-specs.js deleted file mode 100644 index 3aacff95efd..00000000000 --- a/public/test/specs/graphiteDatasource-specs.js +++ /dev/null @@ -1,122 +0,0 @@ -define([ - './helpers', - 'app/plugins/datasource/graphite/datasource' -], function(helpers) { - 'use strict'; - - describe('graphiteDatasource', function() { - var ctx = new helpers.ServiceTestContext(); - - beforeEach(module('grafana.services')); - beforeEach(ctx.providePhase(['backendSrv'])); - - beforeEach(ctx.createService('GraphiteDatasource')); - beforeEach(function() { - ctx.ds = new ctx.service({ url: [''] }); - }); - - describe('When querying influxdb with one target using query editor target spec', function() { - var query = { - rangeRaw: { from: 'now-1h', to: 'now' }, - targets: [{ target: 'prod1.count' }, {target: 'prod2.count'}], - maxDataPoints: 500, - }; - - var results; - var requestOptions; - - beforeEach(function() { - ctx.backendSrv.datasourceRequest = function(options) { - requestOptions = options; - return ctx.$q.when({data: [{ target: 'prod1.count', datapoints: [[10, 1], [12,1]] }]}); - }; - - ctx.ds.query(query).then(function(data) { results = data; }); - ctx.$rootScope.$apply(); - }); - - it('should generate the correct query', function() { - expect(requestOptions.url).to.be('/render'); - }); - - it('should query correctly', function() { - var params = requestOptions.data.split('&'); - expect(params).to.contain('target=prod1.count'); - expect(params).to.contain('target=prod2.count'); - expect(params).to.contain('from=-1h'); - expect(params).to.contain('until=now'); - }); - - it('should exclude undefined params', function() { - var params = requestOptions.data.split('&'); - expect(params).to.not.contain('cacheTimeout=undefined'); - }); - - it('should return series list', function() { - expect(results.data.length).to.be(1); - expect(results.data[0].target).to.be('prod1.count'); - }); - - it('should convert to millisecond resolution', function() { - expect(results.data[0].datapoints[0][0]).to.be(10); - }); - - }); - - describe('building graphite params', function() { - - it('should uri escape targets', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: 'prod1.{test,test2}'}, {target: 'prod2.count'}] - }); - expect(results).to.contain('target=prod1.%7Btest%2Ctest2%7D'); - }); - - it('should replace target placeholder', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: 'series1'}, {target: 'series2'}, {target: 'asPercent(#A,#B)'}] - }); - expect(results[2]).to.be('target=asPercent(series1%2Cseries2)'); - }); - - it('should replace target placeholder for hidden series', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: 'series1', hide: true}, {target: 'sumSeries(#A)', hide: true}, {target: 'asPercent(#A,#B)'}] - }); - expect(results[0]).to.be('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))')); - }); - - it('should replace target placeholder when nesting query references', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: 'series1'}, {target: 'sumSeries(#A)'}, {target: 'asPercent(#A,#B)'}] - }); - expect(results[2]).to.be('target=' + encodeURIComponent("asPercent(series1,sumSeries(series1))")); - }); - - it('should fix wrong minute interval parameters', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: "summarize(prod.25m.count, '25m', 'sum')" }] - }); - expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')")); - }); - - it('should fix wrong month interval parameters', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: "summarize(prod.5M.count, '5M', 'sum')" }] - }); - expect(results[0]).to.be('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')")); - }); - - it('should ignore empty targets', function() { - var results = ctx.ds.buildGraphiteParams({ - targets: [{target: 'series1'}, {target: ''}] - }); - expect(results.length).to.be(2); - }); - - }); - - }); - -}); - diff --git a/public/test/specs/graphiteTargetCtrl-specs.js b/public/test/specs/graphiteTargetCtrl-specs.js deleted file mode 100644 index 42d97ea5fa2..00000000000 --- a/public/test/specs/graphiteTargetCtrl-specs.js +++ /dev/null @@ -1,179 +0,0 @@ -define([ - './helpers', - 'app/plugins/datasource/graphite/gfunc', - 'app/plugins/datasource/graphite/queryCtrl', - 'app/services/uiSegmentSrv' -], function(helpers, gfunc) { - 'use strict'; - - describe('GraphiteQueryCtrl', function() { - var ctx = new helpers.ControllerTestContext(); - - beforeEach(module('grafana.controllers')); - beforeEach(module('grafana.services')); - beforeEach(ctx.providePhase()); - beforeEach(ctx.createControllerPhase('GraphiteQueryCtrl')); - - beforeEach(function() { - ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'}; - - ctx.scope.datasource = ctx.datasource; - ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([])); - }); - - describe('init', function() { - beforeEach(function() { - ctx.scope.init(); - ctx.scope.$digest(); - }); - - it('should validate metric key exists', function() { - expect(ctx.scope.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*'); - }); - - it('should delete last segment if no metrics are found', function() { - expect(ctx.scope.segments[2].value).to.be('select metric'); - }); - - it('should parse expression and build function model', function() { - expect(ctx.scope.functions.length).to.be(2); - }); - }); - - describe('when adding function', function() { - beforeEach(function() { - ctx.scope.target.target = 'test.prod.*.count'; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}])); - ctx.scope.init(); - ctx.scope.$digest(); - - ctx.scope.$parent = { get_data: sinon.spy() }; - ctx.scope.addFunction(gfunc.getFuncDef('aliasByNode')); - }); - - it('should add function with correct node number', function() { - expect(ctx.scope.functions[0].params[0]).to.be(2); - }); - - it('should update target', function() { - expect(ctx.scope.target.target).to.be('aliasByNode(test.prod.*.count, 2)'); - }); - - it('should call get_data', function() { - expect(ctx.scope.$parent.get_data.called).to.be(true); - }); - }); - - describe('when adding function before any metric segment', function() { - beforeEach(function() { - ctx.scope.target.target = ''; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}])); - ctx.scope.init(); - ctx.scope.$digest(); - - ctx.scope.$parent = { get_data: sinon.spy() }; - ctx.scope.addFunction(gfunc.getFuncDef('asPercent')); - }); - - it('should add function and remove select metric link', function() { - expect(ctx.scope.segments.length).to.be(0); - }); - }); - - describe('when initalizing target without metric expression and only function', function() { - beforeEach(function() { - ctx.scope.target.target = 'asPercent(#A, #B)'; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); - ctx.scope.init(); - ctx.scope.$digest(); - ctx.scope.$parent = { get_data: sinon.spy() }; - }); - - it('should not add select metric segment', function() { - expect(ctx.scope.segments.length).to.be(0); - }); - - it('should add both series refs as params', function() { - expect(ctx.scope.functions[0].params.length).to.be(2); - }); - - }); - - describe('when initializing a target with single param func using variable', function() { - beforeEach(function() { - ctx.scope.target.target = 'movingAverage(prod.count, $var)'; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); - ctx.scope.init(); - ctx.scope.$digest(); - ctx.scope.$parent = { get_data: sinon.spy() }; - }); - - it('should add 2 segments', function() { - expect(ctx.scope.segments.length).to.be(2); - }); - - it('should add function param', function() { - expect(ctx.scope.functions[0].params.length).to.be(1); - }); - - }); - - describe('when initalizing target without metric expression and function with series-ref', function() { - beforeEach(function() { - ctx.scope.target.target = 'asPercent(metric.node.count, #A)'; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); - ctx.scope.init(); - ctx.scope.$digest(); - ctx.scope.$parent = { get_data: sinon.spy() }; - }); - - it('should add segments', function() { - expect(ctx.scope.segments.length).to.be(3); - }); - - it('should have correct func params', function() { - expect(ctx.scope.functions[0].params.length).to.be(1); - }); - }); - - describe('when getting altSegments and metricFindQuery retuns empty array', function() { - beforeEach(function() { - ctx.scope.target.target = 'test.count'; - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([])); - ctx.scope.init(); - ctx.scope.getAltSegments(1).then(function(results) { - ctx.altSegments = results; - }); - ctx.scope.$digest(); - ctx.scope.$parent = { get_data: sinon.spy() }; - }); - - it('should have no segments', function() { - expect(ctx.altSegments.length).to.be(0); - }); - - }); - - describe('targetChanged', function() { - beforeEach(function() { - ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}])); - ctx.scope.init(); - ctx.scope.$digest(); - - ctx.scope.$parent = { get_data: sinon.spy() }; - ctx.scope.target.target = ''; - ctx.scope.targetChanged(); - }); - - it('should rebuld target after expression model', function() { - expect(ctx.scope.target.target).to.be('aliasByNode(scaleToSeconds(test.prod.*, 1), 2)'); - }); - - it('should call get_data', function() { - expect(ctx.scope.$parent.get_data.called).to.be(true); - }); - }); - - - }); -}); diff --git a/public/test/test-main.js b/public/test/test-main.js index 4c5d63ede2e..5a7f1eeb437 100644 --- a/public/test/test-main.js +++ b/public/test/test-main.js @@ -113,7 +113,7 @@ require([ var specs = []; for (var file in window.__karma__.files) { - if (/base\/test\/specs.*/.test(file)) { + if (/specs.*/.test(file)) { file = file2moduleName(file); specs.push(file); }