AMBARI-18159 Cover widget views with unit tests. (atkach)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/79775234 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/79775234 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/79775234 Branch: refs/heads/branch-dev-logsearch Commit: 797752341c83b38cedfbad3b89c61736eac69772 Parents: e2fd231 Author: Andrii Tkach <atk...@apache.org> Authored: Tue Aug 16 13:08:50 2016 +0300 Committer: Andrii Tkach <atk...@apache.org> Committed: Tue Aug 16 17:37:03 2016 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 2 + .../views/common/widget/gauge_widget_view.js | 12 +- .../views/common/widget/graph_widget_view.js | 6 +- .../views/common/widget/heatmap_widget_view.js | 7 +- .../common/widget/gauge_widget_view_test.js | 152 ++++- .../common/widget/graph_widget_view_test.js | 552 ++++++++++++++++++- .../common/widget/heatmap_widget_view_test.js | 268 +++++++++ .../common/widget/number_widget_view_test.js | 26 + .../common/widget/template_widget_view_test.js | 44 ++ 9 files changed, 1053 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 00aabff..364f2ed 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -238,6 +238,8 @@ var files = [ 'test/views/common/widget/graph_widget_view_test', 'test/views/common/widget/number_widget_view_test', 'test/views/common/widget/gauge_widget_view_test', + 'test/views/common/widget/template_widget_view_test', + 'test/views/common/widget/heatmap_widget_view_test', 'test/views/common/modal_popups/cluster_check_popup_test', 'test/views/common/modal_popups/hosts_table_list_popup_test', 'test/views/common/modal_popups/dependent_configs_list_popup_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/app/views/common/widget/gauge_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/gauge_widget_view.js b/ambari-web/app/views/common/widget/gauge_widget_view.js index a0bdaea..42224fe 100644 --- a/ambari-web/app/views/common/widget/gauge_widget_view.js +++ b/ambari-web/app/views/common/widget/gauge_widget_view.js @@ -87,7 +87,7 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, { centerTextColor: Em.computed.alias('contentColor'), palette: new Rickshaw.Color.Palette({ - scheme: [ '#FFFFFF', '#D6DDDF'].reverse() + scheme: ['#FFFFFF', '#D6DDDF'].reverse() }), data: function () { @@ -105,17 +105,17 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, { var color_orange = App.healthStatusOrange; if ((isNaN(threshold1) && isNaN(threshold2)) || (isNaN(threshold1) && used <= threshold2) || (isNaN(threshold2) && used <= threshold1) || (!isNaN(threshold2) && (threshold1 > threshold2) && (used > threshold1)) || (!isNaN(threshold2) && (threshold1 < threshold2) && (used <= threshold1))) { this.set('palette', new Rickshaw.Color.Palette({ - scheme: [ '#FFFFFF', color_green ].reverse() + scheme: ['#FFFFFF', color_green].reverse() })); return color_green; } else if ((!isNaN(threshold2) && used.isInRange(threshold1, threshold2)) || (isNaN(threshold2) && used > threshold1)) { this.set('palette', new Rickshaw.Color.Palette({ - scheme: [ '#FFFFFF', color_orange ].reverse() + scheme: ['#FFFFFF', color_orange].reverse() })); return color_orange; } else { this.set('palette', new Rickshaw.Color.Palette({ - scheme: [ '#FFFFFF', color_red ].reverse() + scheme: ['#FFFFFF', color_red].reverse() })); return color_red; } @@ -124,8 +124,8 @@ App.GaugeWidgetView = Em.View.extend(App.WidgetMixin, { // refresh text and color when data in model changed refreshSvg: function () { // remove old svg - var old_svg = $("#" + this.get('id')); - if(old_svg){ + var old_svg = $("#" + this.get('id')); + if (old_svg) { old_svg.remove(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/app/views/common/widget/graph_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/graph_widget_view.js b/ambari-web/app/views/common/widget/graph_widget_view.js index 2413236..6348077 100644 --- a/ambari-web/app/views/common/widget/graph_widget_view.js +++ b/ambari-web/app/views/common/widget/graph_widget_view.js @@ -20,6 +20,8 @@ var App = require('app'); var fileUtils = require('utils/file_utils'); +var CUSTOM_TIME_INDEX = 8; + App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, { templateName: require('templates/common/widget/graph_widget'), @@ -59,7 +61,7 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, { } // Custom start and end time is specified by user - if (this.get('exportTargetView.currentTimeIndex') === 8) { + if (this.get('exportTargetView.currentTimeIndex') === CUSTOM_TIME_INDEX) { return 0; } @@ -290,7 +292,7 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, { */ setTimeRange: function () { if (this.get('isPopup')) { - if (this.get('currentTimeIndex') === 8) { + if (this.get('currentTimeIndex') === CUSTOM_TIME_INDEX) { // Custom start and end time is specified by user this.get('parentView').propertyDidChange('customTimeRange'); } else { http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/app/views/common/widget/heatmap_widget_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/widget/heatmap_widget_view.js b/ambari-web/app/views/common/widget/heatmap_widget_view.js index 6c74420..a7a919b 100644 --- a/ambari-web/app/views/common/widget/heatmap_widget_view.js +++ b/ambari-web/app/views/common/widget/heatmap_widget_view.js @@ -105,6 +105,7 @@ App.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, { /** * calculate value for heatmap widgets + * @returns {Object} */ calculateValues: function () { return this.computeExpression(this.extractExpressions(this.get('content.values')[0]), this.get('metrics')); @@ -113,8 +114,8 @@ App.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, { /** * compute expression - * @param expressions - * @param metrics + * @param {Array} expressions + * @param {Array} metrics * @returns {object} */ computeExpression: function (expressions, metrics) { @@ -148,7 +149,7 @@ App.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, { if (validExpression && this.get('MATH_EXPRESSION_REGEX').test(beforeCompute)) { var value = Number(window.eval(beforeCompute)).toString(); - if (value == "NaN") { + if (value === "NaN") { value = 0 } hostToValueMap[_hostName] = value; http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/test/views/common/widget/gauge_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/widget/gauge_widget_view_test.js b/ambari-web/test/views/common/widget/gauge_widget_view_test.js index 2ba4816..c296327 100644 --- a/ambari-web/test/views/common/widget/gauge_widget_view_test.js +++ b/ambari-web/test/views/common/widget/gauge_widget_view_test.js @@ -21,7 +21,7 @@ require('views/common/widget/gauge_widget_view'); describe('App.GaugeWidgetView', function () { - var view; + var view, chartView; beforeEach(function () { view = App.GaugeWidgetView.create({ @@ -33,6 +33,9 @@ describe('App.GaugeWidgetView', function () { } } }); + chartView = view.chartView.create({ + parentView: view + }); }); afterEach(function () { @@ -40,6 +43,87 @@ describe('App.GaugeWidgetView', function () { view.destroy(); }); + describe("#isOverflowed", function () { + var testCases = [ + { + value: '', + expected: false + }, + { + value: '1', + expected: false + }, + { + value: '0', + expected: false + }, + { + value: '-1', + expected: true + }, + { + value: '1.1', + expected: true + } + ]; + + testCases.forEach(function(test) { + it("value = " + test.value, function() { + view.set('value', test.value); + view.propertyDidChange('isOverflowed'); + expect(view.get('isOverflowed')).to.be.equal(test.expected); + }); + }); + + }); + + describe("#isUnavailable", function () { + var testCases = [ + { + value: '', + isOverflowed: false, + expected: true + }, + { + value: 'a', + isOverflowed: false, + expected: true + }, + { + value: 'a1', + isOverflowed: false, + expected: true + }, + { + value: '1', + isOverflowed: false, + expected: false + }, + { + value: '1.1', + isOverflowed: false, + expected: false + }, + { + value: '1.1', + isOverflowed: true, + expected: true + } + ]; + + testCases.forEach(function(test) { + it("value = " + test.value + + " isOverflowed = " + test.isOverflowed, function() { + view.reopen({ + value: test.value, + isOverflowed: test.isOverflowed + }); + view.propertyDidChange('isUnavailable'); + expect(view.get('isUnavailable')).to.equal(test.expected); + }); + }); + }); + describe("#chartView.contentColor()", function() { var testCases = [ { @@ -166,11 +250,71 @@ describe('App.GaugeWidgetView', function () { view.set('value', test.data.value); view.set('content.properties.warning_threshold', test.data.warningThreshold); view.set('content.properties.error_threshold', test.data.criticalThreshold); - var chartView = view.chartView.create({ - parentView: view - }); expect(chartView.get('contentColor')).to.eql(test.result); }); }); }); + + describe("#chartView.data", function () { + var testCases = [ + { + value: '', + expected: [0, 100] + }, + { + value: 'a', + expected: [0, 100] + }, + { + value: '1.1', + expected: [0, 100] + }, + { + value: '0.1', + expected: ['10', 90] + } + ]; + + testCases.forEach(function(test) { + it("value = " + test.value, function() { + view.set('value', test.value); + expect(chartView.get('data')).to.be.eql(test.expected); + }); + }); + }); + + describe("#chartView.refreshSvg", function () { + var container = { + remove: Em.K + }; + + beforeEach(function() { + this.mock = sinon.stub(window, '$'); + sinon.stub(container, 'remove'); + sinon.stub(chartView, 'appendSvg'); + }); + + afterEach(function() { + container.remove.restore(); + this.mock.restore(); + chartView.appendSvg.restore(); + }); + + it("appendSvg should be called", function() { + chartView.refreshSvg(); + expect(chartView.appendSvg.calledOnce).to.be.true; + }); + + it("should remove old svg", function() { + this.mock.returns(container); + chartView.refreshSvg(); + expect(container.remove.calledOnce).to.be.true; + }); + + it("chart do not have old svg", function() { + this.mock.returns(null); + chartView.refreshSvg(); + expect(container.remove.called).to.be.false; + }); + }); }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/test/views/common/widget/graph_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/widget/graph_widget_view_test.js b/ambari-web/test/views/common/widget/graph_widget_view_test.js index 31c9db0..9c8458c 100644 --- a/ambari-web/test/views/common/widget/graph_widget_view_test.js +++ b/ambari-web/test/views/common/widget/graph_widget_view_test.js @@ -25,7 +25,12 @@ describe('App.GraphWidgetView', function () { var view; beforeEach(function () { - view = App.GraphWidgetView.create(); + view = App.GraphWidgetView.create({ + content: Em.Object.create({ + properties: {} + }), + parentView: Em.Object.create() + }); }); afterEach(function () { @@ -272,4 +277,549 @@ describe('App.GraphWidgetView', function () { }); }); + describe("#timeRange()", function () { + var testCases = [ + { + time_range: null, + currentTimeIndex: 1, + customTimeRange: null, + expected: 3600 + }, + { + time_range: null, + currentTimeIndex: 1, + customTimeRange: 2, + expected: 2 + }, + { + time_range: null, + currentTimeIndex: 8, + customTimeRange: 2, + expected: 0 + }, + { + time_range: 2, + currentTimeIndex: 1, + customTimeRange: null, + expected: 7200 + } + ]; + + testCases.forEach(function(test) { + it("time_range=" + test.time_range + + " currentTimeIndex=" + test.currentTimeIndex + + " customTimeRange=" + test.customTimeRange, function() { + view.set('content.properties.time_range', test.time_range); + view.set('customTimeRange', test.customTimeRange); + view.reopen({ + exportTargetView: Em.Object.create({ + currentTimeIndex: test.currentTimeIndex + }) + }); + view.propertyDidChange('timeRange'); + expect(view.get('timeRange')).to.be.equal(test.expected); + }); + }); + }); + + describe("#drawWidget()", function () { + + beforeEach(function() { + sinon.stub(view, 'calculateValues').returns({}); + view.set('data', null); + }); + + afterEach(function() { + view.calculateValues.restore(); + }); + + it("isLoaded = false", function() { + view.set('isLoaded', false); + view.drawWidget(); + expect(view.get('data')).to.be.null; + }); + + it("isLoaded = true", function() { + view.set('isLoaded', true); + view.drawWidget(); + expect(view.get('data')).to.be.eql({}); + }); + }); + + describe("#calculateValues()", function () { + beforeEach(function() { + this.mockExtract = sinon.stub(view, 'extractExpressions'); + this.mockCompute = sinon.stub(view, 'computeExpression'); + }); + + afterEach(function() { + this.mockExtract.restore(); + this.mockCompute.restore(); + }); + + var testCases = [ + { + metrics: {}, + values: [], + expression: [], + computed: {}, + expected: [] + }, + { + metrics: {}, + values: [{}], + expression: [], + computed: {}, + expected: [] + }, + { + metrics: {}, + values: [{ + value: '${m1}' + }], + expression: ['${m1}'], + computed: { + '${m1}': [] + }, + expected: [] + }, + { + metrics: {}, + values: [{ + value: '${m1}', + name: 'v1' + }], + expression: ['${m1}'], + computed: { + '${m1}': [{ + m1: {} + }] + }, + expected: [ + { + name: 'v1', + data: [{ + m1: {} + }] + } + ] + } + ]; + + testCases.forEach(function(test) { + it("metrics=" + JSON.stringify(test.metrics) + + " values=" + JSON.stringify(test.values) + + " expression=" + test.expression + + " computed=" + test.computed, function() { + view.set('metrics', test.metrics); + view.set('content.values', test.values); + this.mockCompute.returns(test.computed); + this.mockExtract.returns(test.expression); + expect(view.calculateValues()).to.be.eql(test.expected); + }); + }); + }); + + describe("#computeExpression()", function () { + + beforeEach(function() { + sinon.stub(view, 'adjustData', function (dataLinks) { + dataLinks['m1'][1] = [3, 1112]; + }); + }); + + afterEach(function() { + view.adjustData.restore(); + }); + + var testCases = [ + { + expression: '1', + metrics: [], + expected: { + '${1}': [] + }, + adjustDataCalled: false + }, + { + expression: 'm1', + metrics: [], + expected: { + '${m1}': [] + }, + adjustDataCalled: false + }, + { + expression: 'm1', + metrics: [{ + name: 'm1', + data: [] + }], + expected: { + '${m1}': [] + }, + adjustDataCalled: false + }, + { + expression: 'm1', + metrics: [{ + name: 'm1', + data: [ + [null, 1111] + ] + }], + expected: { + '${m1}': [ + [null, 1111] + ] + }, + adjustDataCalled: false + }, + { + expression: 'm1', + metrics: [{ + name: 'm1', + data: [ + [1, 1111] + ] + }], + expected: { + '${m1}': [ + [1, 1111] + ] + }, + adjustDataCalled: false + }, + { + expression: 'm1+1', + metrics: [{ + name: 'm1', + data: [ + [1, 1111] + ] + }], + expected: { + '${m1+1}': [ + [2, 1111] + ] + }, + adjustDataCalled: false + }, + { + expression: 'm1/m2', + metrics: [ + { + name: 'm1', + data: [ + [0, 1111] + ] + }, + { + name: 'm2', + data: [ + [0, 1111] + ] + } + ], + expected: { + '${m1/m2}': [ + [0, 1111] + ] + }, + adjustDataCalled: false + }, + { + expression: 'm1+m2', + metrics: [ + { + name: 'm1', + data: [ + [1, 1111] + ] + }, + { + name: 'm2', + data: [ + [1, 1111], + [2, 1112] + ] + }], + expected: { + '${m1+m2}': [ + [2, 1111], + [5, 1112] + ] + }, + adjustDataCalled: true + } + ]; + + testCases.forEach(function(test) { + it("expression=" + test.expression + + " metrics=" + JSON.stringify(test.metrics), function() { + expect(view.computeExpression(test.expression, test.metrics)).to.be.eql(test.expected); + expect(view.adjustData.calledOnce).to.be.equal(test.adjustDataCalled); + }); + }); + }); + + describe("#addTimeProperties()", function () { + + beforeEach(function() { + sinon.stub(App, 'dateTime').returns(10000); + view.set('timeStep', 15); + }); + + afterEach(function() { + App.dateTime.restore(); + }); + + it("targetView is null", function() { + view.reopen({ + exportTargetView: null + }); + view.set('parentView', null); + expect(view.addTimeProperties([{}])).to.be.empty; + }); + + it("empty metricPaths", function() { + expect(view.addTimeProperties([])).to.be.empty; + }); + + it("timeRange=5", function() { + view.reopen({ + timeRange: 5, + exportTargetView: Em.Object.create({ + isPopup: true + }) + }); + expect(view.addTimeProperties(['m1'])).to.be.eql([ + "m1[5,10,15]" + ]); + }); + + it("timeRange=0, customStartTime=null", function() { + view.reopen({ + timeRange: 0, + exportTargetView: Em.Object.create({ + isPopup: true, + customStartTime: null + }) + }); + expect(view.addTimeProperties(['m1'])).to.be.eql([ + "m1[10,10,15]" + ]); + }); + + it("timeRange=0, customStartTime=1000, customEndTime=null", function() { + view.reopen({ + timeRange: 0, + exportTargetView: Em.Object.create({ + isPopup: true, + customStartTime: 1000, + customEndTime: null + }) + }); + expect(view.addTimeProperties(['m1'])).to.be.eql([ + "m1[10,10,15]" + ]); + }); + + it("timeRange=0, customStartTime=1000, customEndTime=10000", function() { + view.reopen({ + timeRange: 0, + exportTargetView: Em.Object.create({ + isPopup: true, + customStartTime: 1000, + customEndTime: 10000 + }) + }); + expect(view.addTimeProperties(['m1'])).to.be.eql([ + "m1[1,10,15]" + ]); + }); + }); + + describe("#graphView", function () { + var graphView; + + beforeEach(function () { + graphView = view.get('graphView').create({ + parentView: view, + _refreshGraph: Em.K, + $: function() { + return { + closest: function() { + return {on: Em.K} + } + } + } + }); + }); + + describe("#setYAxisFormatter()", function () { + + beforeEach(function () { + sinon.stub(App.ChartLinearTimeView, 'DisplayUnitFormatter'); + graphView.set('yAxisFormatter', null); + }); + + afterEach(function () { + App.ChartLinearTimeView.DisplayUnitFormatter.restore(); + }); + + it("yAxisFormatter should not be set", function () { + graphView.reopen({ + displayUnit: null + }); + graphView.setYAxisFormatter(); + expect(graphView.get('yAxisFormatter')).to.be.null; + }); + + it("yAxisFormatter should be set", function () { + graphView.reopen({ + displayUnit: 'u1' + }); + graphView.setYAxisFormatter(); + expect(graphView.get('yAxisFormatter')).to.be.function; + }); + }); + + describe("#setTimeRange", function () { + + beforeEach(function() { + sinon.stub(graphView.get('parentView'), 'propertyDidChange'); + }); + + afterEach(function() { + graphView.get('parentView').propertyDidChange.restore(); + }); + + it("isPopup=false", function() { + graphView.set('isPopup', false); + graphView.setTimeRange(); + expect(graphView.get('parentView.customTimeRange')).to.be.null; + }); + + it("isPopup=true, currentTimeIndex=8", function() { + graphView.set('isPopup', true); + graphView.set('currentTimeIndex', 8); + graphView.setTimeRange(); + expect(graphView.get('parentView').propertyDidChange.calledWith('customTimeRange')).to.be.true; + }); + + it("isPopup=true, currentTimeIndex=1", function() { + graphView.set('isPopup', true); + graphView.set('currentTimeIndex', 1); + graphView.set('timeUnitSeconds', 10); + expect(graphView.get('parentView.customTimeRange')).to.be.equal(10); + }); + }); + + describe("#id", function () { + + it("should return id", function() { + graphView.set('parentView.content.id', 'g1'); + graphView.propertyDidChange('id'); + expect(graphView.get('id')).to.be.equal('widget_g1_graph'); + }); + }); + + describe("#renderer", function () { + + it("should return area", function() { + graphView.set('parentView.content.properties.graph_type', 'STACK'); + graphView.propertyDidChange('renderer'); + expect(graphView.get('renderer')).to.be.equal('area'); + }); + + it("should return line", function() { + graphView.set('parentView.content.properties.graph_type', ''); + graphView.propertyDidChange('renderer'); + expect(graphView.get('renderer')).to.be.equal('line'); + }); + }); + + describe("#transformToSeries()", function () { + + beforeEach(function() { + sinon.stub(graphView, 'transformData').returns({}); + }); + + afterEach(function() { + graphView.transformData.restore(); + }); + + it("empty data", function() { + expect(graphView.transformToSeries([])).to.be.empty; + }); + + it("should return series", function() { + expect(graphView.transformToSeries([{}])).to.be.eql([{}]); + }); + }); + + describe("#loadData()", function () { + + beforeEach(function() { + sinon.stub(Em.run, 'next', function(context, callback) { + callback.apply(context); + }); + sinon.stub(graphView, '_refreshGraph'); + }); + + afterEach(function() { + Em.run.next.restore(); + graphView._refreshGraph.restore(); + }); + + it("_refreshGraph should be called", function() { + graphView.loadData(); + expect(graphView._refreshGraph.calledOnce).to.be.true; + }); + }); + + describe("#didInsertElement()", function () { + + beforeEach(function() { + sinon.stub(graphView, 'setYAxisFormatter'); + sinon.stub(graphView, 'loadData'); + sinon.stub(Em.run, 'next', Em.clb); + sinon.stub(App, 'tooltip'); + }); + + afterEach(function() { + graphView.setYAxisFormatter.restore(); + graphView.loadData.restore(); + Em.run.next.restore(); + App.tooltip.restore(); + }); + + it("setYAxisFormatter should be called", function() { + graphView.didInsertElement(); + expect(graphView.setYAxisFormatter.calledOnce).to.be.true; + }); + + it("loadData should be called", function() { + graphView.didInsertElement(); + expect(graphView.loadData.calledOnce).to.be.true; + }); + + it("App.tooltip should be called, isPreview=false", function() { + graphView.didInsertElement(); + expect(App.tooltip.getCall(0).args[1]).to.be.eql({ + placement: 'left', + template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner graph-tooltip"></div></div>' + }); + }); + + it("App.tooltip should be called, isPreview=true", function() { + graphView.reopen({ + isPreview: true + }); + graphView.didInsertElement(); + expect(App.tooltip.getCall(0).args[1]).to.be.equal('disable'); + }); + }); + }); }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/test/views/common/widget/heatmap_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/widget/heatmap_widget_view_test.js b/ambari-web/test/views/common/widget/heatmap_widget_view_test.js new file mode 100644 index 0000000..137e664 --- /dev/null +++ b/ambari-web/test/views/common/widget/heatmap_widget_view_test.js @@ -0,0 +1,268 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); +require('views/common/widget/heatmap_widget_view'); + +describe('App.HeatmapWidgetView', function () { + + var view; + + beforeEach(function () { + view = App.HeatmapWidgetView.create({ + controller: Em.Object.create(), + content: Em.Object.create({ + properties: {}, + values: [] + }) + }); + }); + + describe("#onMetricsLoaded()", function () { + + it("isLoaded false", function() { + view.set('isLoaded', false); + view.set('controller.inputMaximum', null); + view.set('content.properties.max_limit', 1); + view.onMetricsLoaded(); + expect(view.get('controller.inputMaximum')).to.be.equal(1); + }); + + it("isLoaded true", function() { + view.set('isLoaded', true); + view.set('controller.inputMaximum', null); + view.set('content.properties.max_limit', 1); + view.onMetricsLoaded(); + expect(view.get('controller.inputMaximum')).to.be.null + }); + }); + + describe("#willDestroyElement()", function () { + var container = { + abort: Em.K + }; + + beforeEach(function() { + sinon.stub(container, 'abort'); + view.set('activeRequest', container); + view.willDestroyElement(); + }); + + afterEach(function() { + container.abort.restore(); + }); + + it("abort should be called", function() { + expect(container.abort.calledOnce).to.be.true; + }); + + it("activeRequest should be null", function() { + expect(view.get('activeRequest')).to.be.null; + }); + }); + + describe("#loadMetrics()", function () { + + beforeEach(function() { + sinon.stub(App.Service, 'find').returns(Em.Object.create({ + isStarted: false + })); + sinon.stub(view, 'onMetricsLoaded'); + }); + + afterEach(function() { + App.Service.find.restore(); + view.onMetricsLoaded.restore(); + }); + + it("onMetricsLoaded should be called", function() { + view.loadMetrics(); + expect(view.onMetricsLoaded.calledOnce).to.be.true; + }); + }); + + describe("#drawWidget()", function () { + + beforeEach(function() { + sinon.stub(view, 'calculateValues').returns({}); + sinon.stub(App.MainChartHeatmapMetric, 'create', function(obj) { + return obj; + }); + }); + + afterEach(function() { + view.calculateValues.restore(); + App.MainChartHeatmapMetric.create.restore(); + }); + + it("isLoaded = false", function() { + view.set('controller.selectedMetric', null); + view.set('isLoaded', false); + view.drawWidget(); + expect(view.get('controller.selectedMetric')).to.be.null; + }); + + it("no loaded racks", function() { + view.set('controller.selectedMetric', null); + view.set('controller.inputMaximum', 1); + view.setProperties({ + isLoaded: true, + racks: [], + content: Em.Object.create({ + displayName: 'm1', + properties: { + display_unit: 'u1' + } + }) + }); + view.drawWidget(); + expect(view.get('controller.selectedMetric')).to.be.eql({ + name: 'm1', + units: 'u1', + maximumValue: 1, + hostNames: [], + hostToValueMap: {} + }); + }); + + it("racks loaded", function() { + view.set('controller.selectedMetric', null); + view.set('controller.inputMaximum', 1); + view.setProperties({ + isLoaded: true, + racks: [{ + hosts: [{ + hostName: 'host1' + }], + isLoaded: true + }], + content: Em.Object.create({ + displayName: 'm1', + properties: { + display_unit: 'u1' + } + }) + }); + view.drawWidget(); + expect(view.get('controller.selectedMetric')).to.be.eql({ + name: 'm1', + units: 'u1', + maximumValue: 1, + hostNames: ['host1'], + hostToValueMap: {} + }); + }); + }); + + describe("#calculateValues()", function () { + + beforeEach(function() { + sinon.stub(view, 'computeExpression').returns({}); + sinon.stub(view, 'extractExpressions'); + }); + + afterEach(function() { + view.computeExpression.restore(); + view.extractExpressions.restore(); + }); + + it("calculateValues should return object", function() { + view.set('content.values', [{}]); + view.set('metrics', [{}]); + expect(view.calculateValues()).to.be.eql({}); + }); + }); + + describe("#computeExpression()", function () { + + var testCases = [ + { + expressions: [], + metrics: [], + expected: {} + }, + { + expressions: ['m2'], + metrics: [{ + name: 'm1', + hostName: 'host1' + }], + expected: {} + }, + { + expressions: ['1'], + metrics: [{ + name: 'm1', + hostName: 'host1' + }], + expected: { + 'host1': '1' + } + }, + { + expressions: ['m1'], + metrics: [{ + name: 'm1', + hostName: 'host1', + data: '2' + }], + expected: { + 'host1': '2' + } + }, + { + expressions: ['m1+1'], + metrics: [{ + name: 'm1', + hostName: 'host1', + data: '2' + }], + expected: { + 'host1': '3' + } + }, + { + expressions: ['m1'], + metrics: [{ + name: 'm1', + hostName: 'host1', + data: '0/0' + }], + expected: { + 'host1': 0 + } + }, + { + expressions: ['m1-m2'], + metrics: [{ + name: 'm1', + hostName: 'host1', + data: '2' + }], + expected: {} + } + ]; + + testCases.forEach(function(test) { + it("expressions=" + JSON.stringify(test.expressions) + + " metrics=" + JSON.stringify(test.metrics), function() { + expect(view.computeExpression(test.expressions, test.metrics)).to.be.eql(test.expected); + }); + }); + }); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/test/views/common/widget/number_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/widget/number_widget_view_test.js b/ambari-web/test/views/common/widget/number_widget_view_test.js index f82819e..5105bd9 100644 --- a/ambari-web/test/views/common/widget/number_widget_view_test.js +++ b/ambari-web/test/views/common/widget/number_widget_view_test.js @@ -40,6 +40,32 @@ describe('App.NumberWidgetView', function () { view.destroy(); }); + describe("#displayValue", function () { + var testCases = [ + { + value: '', + expected: Em.I18n.t('common.na') + }, + { + value: 'a', + expected: Em.I18n.t('common.na') + }, + { + value: '1', + expected: '1u' + } + ]; + + testCases.forEach(function(test) { + it("value = " + test.value, function() { + view.set('value', test.value); + view.set('content.properties.display_unit', 'u'); + view.propertyDidChange('displayValue'); + expect(view.get('displayValue')).to.be.equal(test.expected); + }); + }); + }); + describe("#contentColor()", function() { var testCases = [ { http://git-wip-us.apache.org/repos/asf/ambari/blob/79775234/ambari-web/test/views/common/widget/template_widget_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/widget/template_widget_view_test.js b/ambari-web/test/views/common/widget/template_widget_view_test.js new file mode 100644 index 0000000..f3db9ee --- /dev/null +++ b/ambari-web/test/views/common/widget/template_widget_view_test.js @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); +require('views/common/widget/template_widget_view'); + +describe('App.TemplateWidgetView', function () { + + var view; + + beforeEach(function () { + view = App.TemplateWidgetView.create(); + }); + + describe("#displayValue", function () { + + it("empty value", function() { + view.set('value', ''); + view.propertyDidChange('displayValue'); + expect(view.get('displayValue')).to.be.equal(Em.I18n.t('common.na')); + }); + + it("value not empty", function() { + view.set('value', 'val'); + view.propertyDidChange('displayValue'); + expect(view.get('displayValue')).to.be.equal('val'); + }); + }); +}); \ No newline at end of file