Repository: ambari Updated Branches: refs/heads/trunk 817a7e34e -> 852d8af2f
AMBARI-5612. Unit tests for object_utils, date, ui_effects, updater. (Denis Buzhor via onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/852d8af2 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/852d8af2 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/852d8af2 Branch: refs/heads/trunk Commit: 852d8af2f47296b6e036d7ca4590e3d33e80c4cb Parents: 817a7e3 Author: Oleg Nechiporenko <[email protected]> Authored: Tue Apr 29 15:10:06 2014 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Tue Apr 29 15:10:06 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 3 + ambari-web/app/utils/date.js | 2 +- ambari-web/app/utils/object_utils.js | 23 ---- ambari-web/app/utils/ui_effects.js | 20 ++-- .../views/main/service/info/metrics/yarn/qmr.js | 6 +- ambari-web/test/utils/date_test.js | 104 ++++++++++++++++++- ambari-web/test/utils/object_utils_test.js | 80 ++++++++++++++ ambari-web/test/utils/ui_effects_test.js | 48 +++++++++ ambari-web/test/utils/updater_test.js | 87 ++++++++++++++++ 9 files changed, 332 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/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 7e8c040..e383bf7 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -101,6 +101,9 @@ require('test/utils/string_utils_test'); require('test/utils/lazy_loading_test'); require('test/utils/helper_test'); require('test/utils/component_test'); +require('test/utils/object_utils_test'); +require('test/utils/ui_effects_test'); +require('test/utils/updater_test'); require('test/views/common/chart/linear_time_test'); require('test/views/common/filter_view_test'); require('test/views/common/table_view_test'); http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/app/utils/date.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/date.js b/ambari-web/app/utils/date.js index 37d8959..bfe524f 100644 --- a/ambari-web/app/utils/date.js +++ b/ambari-web/app/utils/date.js @@ -42,7 +42,7 @@ module.exports = { */ dateFormatZeroFirst: function (time) { if (time < 10) return '0' + time; - return time; + return "" + time; }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/app/utils/object_utils.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/object_utils.js b/ambari-web/app/utils/object_utils.js index f215471..c647a6a 100644 --- a/ambari-web/app/utils/object_utils.js +++ b/ambari-web/app/utils/object_utils.js @@ -68,28 +68,5 @@ module.exports = { return leaf; } return r(obj,''); - }, - - /** - * Gets value of property path. - * - * @param {Object} object - * @param {String} propertyPath - * Format is 'a.b.c' - * @return Returns <code>undefined</code> when path does not exist. - */ - getProperty: function (object, propertyPath) { - var props = propertyPath.split('.'); - for ( var c = 0; c < props.length - 1 && object; c++) { - object = object[props[c]]; - if (object === null) { - break; - } - } - if (object != null) { - return object[props[props.length - 1]]; - } - return undefined; } - }; http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/app/utils/ui_effects.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ui_effects.js b/ambari-web/app/utils/ui_effects.js index 57c431e..fae2e23 100644 --- a/ambari-web/app/utils/ui_effects.js +++ b/ambari-web/app/utils/ui_effects.js @@ -19,20 +19,20 @@ module.exports = { /** * - * @param node - DOM element which blinking - * @param delay - overall time of blinking - * @param callback - * @param interval - change frequence of blinking + * @param node {DOMElement} - DOM element which blinking + * @param delay {number} - overall time of blinking + * @param callback {function} + * @param interval {number} - change frequence of blinking */ pulsate: function (node, delay, callback, interval) { var self = this; /** * execute single blink - * @param interval - time of single blink - * @param callback - * @param opacity - * @param iteration - current iteration(default amount of iterations: 10) - * @param isReverse - flag, that mean opacity increase or decrease + * @param interval {number} - time of single blink + * @param callback {function} + * @param opacity {string|number} + * @param iteration {number} - current iteration(default amount of iterations: 10) + * @param isReverse {boolean} - flag, that mean opacity increase or decrease */ var blink = function (interval, callback, opacity, iteration, isReverse) { var iterations = 10; @@ -63,4 +63,4 @@ module.exports = { callback(); } } -}; \ No newline at end of file +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/app/views/main/service/info/metrics/yarn/qmr.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/metrics/yarn/qmr.js b/ambari-web/app/views/main/service/info/metrics/yarn/qmr.js index b923d19..787109c 100644 --- a/ambari-web/app/views/main/service/info/metrics/yarn/qmr.js +++ b/ambari-web/app/views/main/service/info/metrics/yarn/qmr.js @@ -58,8 +58,8 @@ App.ChartServiceMetricsYARN_QMR = App.ChartLinearTimeView.extend({ queueNames.forEach(function (qName) { var qPath = qName.replace(/\//g, '.'); var displayName; - var allocatedData = objUtils.getProperty(jsonData.metrics.yarn.Queue, qPath + '.AllocatedMB'); - var availableData = objUtils.getProperty(jsonData.metrics.yarn.Queue, qPath + '.AvailableMB'); + var allocatedData = Em.get(jsonData.metrics.yarn.Queue, qPath + '.AllocatedMB'); + var availableData = Em.get(jsonData.metrics.yarn.Queue, qPath + '.AvailableMB'); displayName = Em.I18n.t('services.service.info.metrics.yarn.queueMemoryResource.displayName').format(qName); var seriesData = null; if (allocatedData != null && availableData != null) { @@ -82,4 +82,4 @@ App.ChartServiceMetricsYARN_QMR = App.ChartLinearTimeView.extend({ } return seriesArray; } -}); \ No newline at end of file +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/test/utils/date_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/date_test.js b/ambari-web/test/utils/date_test.js index b67b176..ea5f1e4 100644 --- a/ambari-web/test/utils/date_test.js +++ b/ambari-web/test/utils/date_test.js @@ -27,7 +27,9 @@ describe('date', function () { var correct_tests = Em.A([ {t: 1349752195000, e: 'Tue, Oct 09, 2012 03:09', e2: 'Tue Oct 09 2012'}, {t: 1367752195000, e: 'Sun, May 05, 2013 11:09', e2: 'Sun May 05 2013'}, - {t: 1369952195000, e: 'Thu, May 30, 2013 22:16', e2: 'Thu May 30 2013'} + {t: 1369952195000, e: 'Thu, May 30, 2013 22:16', e2: 'Thu May 30 2013'}, + {t: 1369952195000, e: 'Thu, May 30, 2013 22:16:35', e2: 'Thu May 30 2013', showSeconds: true }, + {t: 1369952195000, e: 'Thu, May 30, 2013 22:16:35:000', e2: 'Thu May 30 2013', showSeconds: true, showMilliseconds: true } ]); var incorrect_tests = Em.A([ @@ -40,11 +42,32 @@ describe('date', function () { {t: function(){}} ]); + describe('#dateFormatZeroFirst()', function() { + var tests = [ + { + t: 2, + e: '02', + m: 'should convert to `02`' + }, + { + t: 10, + e: '10', + m: 'should convert to `10`' + } + ]; + tests.forEach(function(test) { + it(test.m, function() { + expect(date.dateFormatZeroFirst(test.t)).to.eql(test.e); + }); + }); + }); + describe('#dateFormat', function() { describe('Correct timestamps', function(){ correct_tests.forEach(function(test) { - it(test.t, function() { - expect(date.dateFormat(test.t)).to.equal(test.e); + var testMessage = test.t + ' `showSeconds` ' + !!test.showSeconds + '`showMilliseconds` ' + !!test.showMilliseconds; + it(testMessage, function() { + expect(date.dateFormat(test.t, test.showSeconds, test.showMilliseconds)).to.equal(test.e); }); }); }); @@ -79,6 +102,22 @@ describe('date', function () { }); }); + describe('#startTime()', function() { + var today = new Date(); + var tests = [ + { t: 1349752195000, e: 'Tue Oct 09 2012 06:09' }, + { t: -10000000, e: 'Not started' }, + { t: today.getTime(), e: 'Today {0}:{1}'.format(date.dateFormatZeroFirst(today.getHours()), date.dateFormatZeroFirst(today.getMinutes())) }, + { t: today, e: ''} + ]; + tests.forEach(function(test) { + var testMessage = 'should conver {0} to {1}'.format(test.t, test.e); + it(testMessage, function() { + expect(date.startTime(test.t)).to.be.eql(test.e); + }); + }); + }); + describe('#timingFormat', function() { var tests = Em.A([ {i: '30', e:'30 ms'}, @@ -118,13 +157,70 @@ describe('date', function () { describe('#duration', function() { var tests = Em.A([ {startTime: 1, endTime: 2, e: 1}, - {startTime: 0, endTime: 2000, e: 0} + {startTime: 0, endTime: 2000, e: 0}, + {startTime: 200, endTime: 0, e: 19800} ]); + + beforeEach(function() { + sinon.stub(App, 'dateTime', function () { return 20000; }); + }); + tests.forEach(function(test) { it(test.startTime + ' ' + test.endTime, function() { expect(date.duration(test.startTime, test.endTime)).to.equal(test.e); }); }); + + afterEach(function() { + App.dateTime.restore(); + }); + }); + + describe('#durationSummary()', function() { + var tests = [ + { + startTimestamp: 1349752195000, + endTimestamp: 1349752199000, + e: '4.00 secs' + }, + { + startTimestamp: 1349752195000, + endTimestamp: 1367752195000, + e: '208.33 days' + }, + { + startTimestamp: -10000000, + endTimestamp: 1367752195000, + e: Em.I18n.t('common.na') + }, + { + startTimestamp: 1349752195000, + endTimestamp: -1, + stubbed: true, + e: '0 secs' + }, + { + startTimestamp: 1000, + endTimestamp: -1, + stubbed: true, + e: '19.00 secs' + } + ]; + + beforeEach(function() { + sinon.stub(App, 'dateTime', function () { return 20000; }); + }); + + tests.forEach(function(test) { + var testMessage = 'duration between {0} and {1} is {2}'.format(test.startTimestamp, test.endTimestamp, test.e) + (test.stubbed ? " App.dateTime() is stubbed" : ""); + it(testMessage, function() { + expect(date.durationSummary(test.startTimestamp, test.endTimestamp)).to.be.eql(test.e); + }); + }); + + afterEach(function() { + App.dateTime.restore(); + }); }); }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/test/utils/object_utils_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/object_utils_test.js b/ambari-web/test/utils/object_utils_test.js new file mode 100644 index 0000000..92c0cfe --- /dev/null +++ b/ambari-web/test/utils/object_utils_test.js @@ -0,0 +1,80 @@ +/** + * 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 objectUtils = require('utils/object_utils'); + +describe('utils/object_utils', function() { + describe('#recursiveTree()', function() { + var testObj = { + a1: { + a2: 'v1', + a3: { + a4: { + a5: { + a6: 'v2', + a7: 'v3' + } + } + } + } + }; + it('should return correct tree of childs', function(){ + var result = objectUtils.recursiveTree(testObj); + expect(result).to.eql('a2 (/a1)<br/>a5 (/a1/a3/a4)<br/>'); + }); + + it('should return `null` if type missed', function() { + var result = objectUtils.recursiveTree('{ a1: "v1"}'); + expect(result).to.be.null; + }); + }); + describe('#recursiveKeysCount()', function() { + var tests = [ + { + m: 'should return 1 child', + e: 3, + obj: { + a1: { + a2: 'v1', + a3: 'v2', + a4: { + a5: 'v3' + } + } + } + }, + { + m: 'should return 1 childs', + e: 1, + obj: { + a1: 'c1' + } + }, + { + m: 'should return `null`', + e: null, + obj: 'a1' + } + ]; + tests.forEach(function(test){ + it(test.m, function() { + expect(objectUtils.recursiveKeysCount(test.obj)).to.be.eql(test.e); + }); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/test/utils/ui_effects_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/ui_effects_test.js b/ambari-web/test/utils/ui_effects_test.js new file mode 100644 index 0000000..7126e5d --- /dev/null +++ b/ambari-web/test/utils/ui_effects_test.js @@ -0,0 +1,48 @@ +/** + * 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 ui_utils = require('utils/ui_effects'); +var App = require('app'); + +describe('utils/ui_effects', function(){ + describe('#pulsate()', function(){ + beforeEach(function(){ + $('body').append('<div id="pulsate-test-dom"></div>'); + this.clock = sinon.useFakeTimers(); + }); + + it('opacity should be 0.2 on 5-th iteration', function() { + var domEl = $('#pulsate-test-dom'); + ui_utils.pulsate(domEl, 1000); + this.clock.tick(300); + expect(parseFloat(domEl.css('opacity')).toFixed(1)).to.eql('0.2'); + }); + it('should call callback at the end', function() { + var domEl = $('#pulsate-test-dom'); + var stub = sinon.stub(); + ui_utils.pulsate(domEl, 1000, stub); + this.clock.tick(2000); + expect(stub.calledOnce).to.be.ok; + }); + + afterEach(function(){ + $('#pulsate-test-dom').remove(); + this.clock.restore(); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/852d8af2/ambari-web/test/utils/updater_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/updater_test.js b/ambari-web/test/utils/updater_test.js new file mode 100644 index 0000000..a80c59c --- /dev/null +++ b/ambari-web/test/utils/updater_test.js @@ -0,0 +1,87 @@ +/** + * 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'); + +describe('utils/updater', function() { + describe('#App.updater', function() { + beforeEach(function() { + this.clock = sinon.useFakeTimers(); + }); + + var tests = { + t1: { + obj: Em.Object.create({ + method: sinon.spy(), + isWorking: true + }), + m: 'method called once with default interval in 15 000 ms' + }, + t2: { + obj: Em.Object.create({ + method: function() {} + }), + m: 'should return false if key name is invalid or absent' + }, + t3: { + obj: Em.Object.create({ + method2: sinon.spy(), + isWorking: true + }), + m: 'method should be called immediately' + }, + t4: { + obj: Em.Object.create({ + method3: sinon.spy(), + isWorking: true + }), + m: 'method call should be ignored if `isWorking` set to false' + } + }; + + it(tests.t1.m, function() { + App.updater.run(tests.t1.obj, 'method', 'isWorking'); + this.clock.tick(15000); + expect(tests.t1.obj.method.called).to.be.ok; + }); + + it(tests.t2.m, function() { + var methodCall = App.updater.run(tests.t2.obj, 'method', 'isWorking'); + expect(methodCall).to.be.false; + }); + + it(tests.t3.m, function() { + App.updater.run(tests.t3.obj, 'method2', 'isWorking'); + App.updater.immediateRun('method2'); + expect(tests.t3.obj.method2.called).to.be.ok; + }); + + it(tests.t4.m, function() { + App.updater.run(tests.t4.obj, 'method3', 'isWorking'); + this.clock.tick(10000); + tests.t4.obj.set('isWorking', false); + this.clock.tick(5000); + expect(tests.t4.obj.method3.called).to.be.false; + }); + + + afterEach(function() { + this.clock.restore(); + }); + }); +});
