You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2016/02/03 17:14:29 UTC
ambari git commit: AMBARI-14898. Alerts: Ability to customize props
and thresholds on SCRIPT alerts via Ambari Web UI (onechiporenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 46f6030b0 -> 6d9e05995
AMBARI-14898. Alerts: Ability to customize props and thresholds on SCRIPT alerts via Ambari Web UI (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6d9e0599
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6d9e0599
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6d9e0599
Branch: refs/heads/trunk
Commit: 6d9e05995f6815a600021e0e84f3f29518989b36
Parents: 46f6030
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Wed Feb 3 16:02:23 2016 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Wed Feb 3 18:12:10 2016 +0200
----------------------------------------------------------------------
.../alerts/definition_configs_controller.js | 29 ++++++
.../app/mappers/alert_definitions_mapper.js | 36 ++++---
ambari-web/app/models/alerts/alert_config.js | 62 +++++++++++-
.../app/models/alerts/alert_definition.js | 4 +-
ambari-web/app/styles/alerts.less | 4 +
.../alerts/configs/alert_config_parameter.hbs | 33 ++++++
.../main/alerts/definition_configs_view.js | 10 ++
.../definitions_configs_controller_test.js | 44 +++++++-
.../mappers/alert_definitions_mapper_test.js | 45 ++++++++-
.../test/models/alerts/alert_config_test.js | 100 +++++++++++++++++++
10 files changed, 341 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
index 1b66f60..3fd5510 100644
--- a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
+++ b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
@@ -320,6 +320,23 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
})
]);
+ var mixins = {
+ STRING: App.AlertConfigProperties.Parameters.StringMixin,
+ NUMERIC: App.AlertConfigProperties.Parameters.NumericMixin,
+ PERCENT: App.AlertConfigProperties.Parameters.PercentageMixin
+ };
+ alertDefinition.get('parameters').forEach(function (parameter) {
+ var mixin = mixins[parameter.get('type')] || {}; // validation depends on parameter-type
+ result.push(App.AlertConfigProperties.Parameter.create(mixin, {
+ value: isWizard ? '' : parameter.get('value'),
+ apiProperty: parameter.get('name'),
+ label: isWizard ? '' : parameter.get('displayName'),
+ threshold: isWizard ? '' : parameter.get('threshold'),
+ units: isWizard ? '' : parameter.get('units'),
+ type: isWizard ? '' : parameter.get('type'),
+ }));
+ });
+
return result;
},
@@ -478,6 +495,9 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
getPropertiesToUpdate: function (onlyChanged) {
var propertiesToUpdate = {};
var configs = onlyChanged ? this.get('configs').filterProperty('wasChanged') : this.get('configs');
+ configs = configs.filter(function (c) {
+ return c.get('name') !== 'parameter';
+ });
configs.forEach(function (property) {
var apiProperties = property.get('apiProperty');
var apiFormattedValues = property.get('apiFormattedValue');
@@ -521,6 +541,15 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
}, this);
}, this);
+ // `source.parameters` is an array and should be updated separately from other configs
+ if (this.get('content.parameters.length')) {
+ propertiesToUpdate['AlertDefinition/source/parameters'] = this.get('content.rawSourceData.parameters');
+ var parameterConfigs = this.get('configs').filterProperty('name', 'parameter');
+ parameterConfigs.forEach(function (parameter) {
+ propertiesToUpdate['AlertDefinition/source/parameters'].findProperty('name', parameter.get('apiProperty')).value = parameter.get('apiFormattedValue');
+ });
+ }
+
return propertiesToUpdate;
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/mappers/alert_definitions_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_definitions_mapper.js b/ambari-web/app/mappers/alert_definitions_mapper.js
index b027d67..7aae518 100644
--- a/ambari-web/app/mappers/alert_definitions_mapper.js
+++ b/ambari-web/app/mappers/alert_definitions_mapper.js
@@ -17,8 +17,6 @@
var App = require('app');
-var stringUtils = require('utils/string_utils');
-
App.alertDefinitionsMapper = App.QuickDataMapper.create({
model: App.AlertDefinition,
@@ -44,7 +42,7 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
reporting: {
item: 'id'
},
- parameters_key: 'reporting',
+ parameters_key: 'parameters',
parameters_type: 'array',
parameters: {
item: 'id'
@@ -76,21 +74,11 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
connection_timeout: 'AlertDefinition.source.uri.connection_timeout'
},
- parameterConfig: {
- id: 'AlertDefinition.source.parameters.id',
- name: 'AlertDefinition.source.parameters.name',
- display_name: 'AlertDefinition.source.parameters.display_name',
- units: 'AlertDefinition.source.parameters.units',
- value: 'AlertDefinition.source.parameters.value',
- description: 'AlertDefinition.source.parameters.description',
- type: 'AlertDefinition.source.parameters.type',
- threshold: 'AlertDefinition.source.parameters.threshold'
- },
-
map: function (json) {
console.time('App.alertDefinitionsMapper execution time');
if (json && json.items) {
var self = this,
+ parameters = [],
alertDefinitions = [],
alertReportDefinitions = [],
alertMetricsSourceDefinitions = [],
@@ -123,8 +111,27 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
}
}
+ var convertedParameters = [];
+ var sourceParameters = item.AlertDefinition.source.parameters;
+ if (Array.isArray(sourceParameters)) {
+ sourceParameters.forEach(function (parameter) {
+ convertedParameters.push({
+ id: item.AlertDefinition.id + parameter.name,
+ name: parameter.name,
+ display_name: parameter.display_name,
+ units: parameter.units,
+ value: parameter.value,
+ description: parameter.description,
+ type: parameter.type,
+ threshold: parameter.threshold
+ });
+ });
+ }
+
alertReportDefinitions = alertReportDefinitions.concat(convertedReportDefinitions);
+ parameters = parameters.concat(convertedParameters);
item.reporting = convertedReportDefinitions;
+ item.parameters = convertedParameters;
rawSourceData[item.AlertDefinition.id] = item.AlertDefinition.source;
item.AlertDefinition.description = item.AlertDefinition.description || '';
@@ -207,6 +214,7 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
// load all mapped data to model
App.store.loadMany(this.get('reportModel'), alertReportDefinitions);
+ App.store.loadMany(this.get('parameterModel'), parameters);
App.store.loadMany(this.get('metricsSourceModel'), alertMetricsSourceDefinitions);
this.setMetricsSourcePropertyLists(this.get('metricsSourceModel'), alertMetricsSourceDefinitions);
App.store.loadMany(this.get('metricsUriModel'), alertMetricsUriDefinitions);
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/models/alerts/alert_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alerts/alert_config.js b/ambari-web/app/models/alerts/alert_config.js
index 4ef3edd..a9a8154 100644
--- a/ambari-web/app/models/alerts/alert_config.js
+++ b/ambari-web/app/models/alerts/alert_config.js
@@ -139,6 +139,8 @@ App.AlertConfigProperty = Ember.Object.extend({
return App.AlertConfigThresholdView;
case 'radioButton':
return App.AlertConfigRadioButtonView;
+ case 'parameter':
+ return App.AlertConfigParameterView;
default:
}
}.property('displayType'),
@@ -331,9 +333,7 @@ App.AlertConfigProperties = {
* Custom css-class for different badges
* type {string}
*/
- badgeCssClass: function () {
- return 'alert-state-' + this.get('badge');
- }.property('badge'),
+ badgeCssClass: Em.computed.format('alert-state-{0}', 'badge'),
/**
* Determines if <code>value</code> or <code>text</code> were changed
@@ -476,10 +476,66 @@ App.AlertConfigProperties = {
displayType: 'textArea',
classNames: 'alert-config-text-area',
apiProperty: Em.computed.ifThenElse('isJMXMetric', 'source.jmx.value', 'source.ganglia.value')
+ }),
+
+ Parameter: App.AlertConfigProperty.extend({
+
+ name: 'parameter',
+
+ displayType: 'parameter',
+
+ badge: Em.computed.alias('threshold'),
+
+ thresholdNotExists: Em.computed.empty('threshold'),
+
+ /**
+ * Custom css-class for different badges
+ * type {string}
+ */
+ badgeCssClass: Em.computed.format('alert-state-{0}', 'badge'),
+
})
};
+App.AlertConfigProperties.Parameters = {
+ StringMixin: Em.Mixin.create({
+ isValid: function () {
+ var value = this.get('value');
+ return String(value).trim() !== '';
+ }.property('value')
+ }),
+ NumericMixin: Em.Mixin.create({
+ isValid: function () {
+ var value = this.get('value');
+ if (!value) {
+ return false;
+ }
+ value = ('' + value).trim();
+ if (!numericUtils.isPositiveNumber(value)) {
+ return false;
+ }
+ value = parseFloat(value);
+ return !isNaN(value);
+ }.property('value')
+ }),
+ PercentageMixin: Em.Mixin.create({
+ isValid: function () {
+ var value = this.get('value');
+ if (!value) {
+ return false;
+ }
+ if (!validator.isValidFloat(value) || !numericUtils.isPositiveNumber(value)) {
+ return false;
+ }
+ value = String(value).trim();
+ value = parseFloat(value);
+
+ return !isNaN(value) && value > 0 && value <= 100;
+ }.property('value')
+ })
+
+};
App.AlertConfigProperties.Thresholds = {
OkThreshold: App.AlertConfigProperties.Threshold.extend({
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/models/alerts/alert_definition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alerts/alert_definition.js b/ambari-web/app/models/alerts/alert_definition.js
index 3f59e86..e91bd4f 100644
--- a/ambari-web/app/models/alerts/alert_definition.js
+++ b/ambari-web/app/models/alerts/alert_definition.js
@@ -315,8 +315,8 @@ App.AlertDefinition.reopenClass({
App.AlertDefinitionParameter = DS.Model.extend({
name: DS.attr('string'),
displayName: DS.attr('string'),
- unit: DS.attr('string'),
- value: DS.attr('number'),
+ units: DS.attr('string'),
+ value: DS.attr('string'),
description: DS.attr('string'),
type: DS.attr('string'),
threshold: DS.attr('string')
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/styles/alerts.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/alerts.less b/ambari-web/app/styles/alerts.less
index 2eabbe2..1063ecf 100644
--- a/ambari-web/app/styles/alerts.less
+++ b/ambari-web/app/styles/alerts.less
@@ -300,6 +300,10 @@
width: 170px;
}
+ .stuck-left {
+ margin-left: 0!important;
+ }
+
.controls.shifted {
margin-left: 190px;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/templates/main/alerts/configs/alert_config_parameter.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/configs/alert_config_parameter.hbs b/ambari-web/app/templates/main/alerts/configs/alert_config_parameter.hbs
new file mode 100644
index 0000000..fffa7bd
--- /dev/null
+++ b/ambari-web/app/templates/main/alerts/configs/alert_config_parameter.hbs
@@ -0,0 +1,33 @@
+{{!
+* 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.
+}}
+
+<div>
+ {{#if view.property.threshold}}
+ <div class="span2 badge-container">
+ <span {{bindAttr class="view.property.badgeCssClass :alert-parameter-badge :alert-state-single-host view.property.threshold:label"}}>
+ {{view.property.badge}}
+ </span>
+ </div>
+ {{/if}}
+ <div {{bindAttr class="view.bigInput:span12:span3 view.property.units:input-append view.property.thresholdNotExists:stuck-left"}}>
+ {{view Em.TextField valueBinding="view.property.value" disabledBinding="view.property.isDisabled" class ="view.bigInput:span12:span7"}}
+ {{#if view.property.units}}
+ <span class="add-on">{{view.property.units}}</span>
+ {{/if}}
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/app/views/main/alerts/definition_configs_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/definition_configs_view.js b/ambari-web/app/views/main/alerts/definition_configs_view.js
index d909367..00e26d4 100644
--- a/ambari-web/app/views/main/alerts/definition_configs_view.js
+++ b/ambari-web/app/views/main/alerts/definition_configs_view.js
@@ -93,3 +93,13 @@ App.AlertConfigRadioButtonView = Em.Checkbox.extend({
classNameBindings: ['property.classNames']
});
+
+App.AlertConfigParameterView = Em.View.extend({
+
+ templateName: require('templates/main/alerts/configs/alert_config_parameter'),
+
+ bigInput: Em.computed.equal('property.type', 'STRING'),
+
+ classNameBindings: ['property.classNames', 'parentView.basicClass']
+
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
index ae25d2d..4061f35 100644
--- a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
@@ -249,6 +249,10 @@ describe('App.MainAlertDefinitionConfigsController', function () {
scope: 'HOST',
description: 'alertDefinitionDescription',
interval: 60,
+ parameters: [
+ Em.Object.create({}),
+ Em.Object.create({}),
+ ],
reporting: [
Em.Object.create({
type: 'warning',
@@ -270,13 +274,13 @@ describe('App.MainAlertDefinitionConfigsController', function () {
it('isWizard = true', function () {
controller.set('isWizard', true);
var result = controller.renderScriptConfigs();
- expect(result.length).to.equal(8);
+ expect(result.length).to.equal(10);
});
it('isWizard = false', function () {
controller.set('isWizard', false);
var result = controller.renderScriptConfigs();
- expect(result.length).to.equal(2);
+ expect(result.length).to.equal(4);
});
});
@@ -477,6 +481,42 @@ describe('App.MainAlertDefinitionConfigsController', function () {
expect(result).to.eql(testCase.result);
});
});
+
+ describe('`source/parameters` for SCRIPT configs', function () {
+
+ beforeEach(function () {
+ controller.set('content', Em.Object.create({
+ parameters: [
+ Em.Object.create({name: 'p1', value: 'v1'}),
+ Em.Object.create({name: 'p2', value: 'v2'}),
+ Em.Object.create({name: 'p3', value: 'v3'}),
+ Em.Object.create({name: 'p4', value: 'v4'})
+ ],
+ rawSourceData: {
+ parameters: [
+ {name: 'p1', value: 'v1'},
+ {name: 'p2', value: 'v2'},
+ {name: 'p3', value: 'v3'},
+ {name: 'p4', value: 'v4'}
+ ]
+ }
+ }));
+ controller.set('configs', [
+ Em.Object.create({apiProperty:'p1', apiFormattedValue: 'v11', wasChanged: true, name: 'parameter'}),
+ Em.Object.create({apiProperty:'p2', apiFormattedValue: 'v21', wasChanged: true, name: 'parameter'}),
+ Em.Object.create({apiProperty:'p3', apiFormattedValue: 'v31', wasChanged: true, name: 'parameter'}),
+ Em.Object.create({apiProperty:'p4', apiFormattedValue: 'v41', wasChanged: true, name: 'parameter'})
+ ]);
+ this.result = controller.getPropertiesToUpdate();
+ });
+
+ it('should update parameters', function () {
+ expect(this.result['AlertDefinition/source/parameters']).to.have.property('length').equal(4);
+ expect(this.result['AlertDefinition/source/parameters'].mapProperty('value')).to.be.eql(['v11', 'v21', 'v31', 'v41']);
+ });
+
+ });
+
});
describe('#changeType()', function () {
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/test/mappers/alert_definitions_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/alert_definitions_mapper_test.js b/ambari-web/test/mappers/alert_definitions_mapper_test.js
index 6626187..564bf1d 100644
--- a/ambari-web/test/mappers/alert_definitions_mapper_test.js
+++ b/ambari-web/test/mappers/alert_definitions_mapper_test.js
@@ -21,7 +21,8 @@ require('mappers/alert_definitions_mapper');
var testHelpers = require('test/helpers');
describe('App.alertDefinitionsMapper', function () {
- describe.skip('#map', function () {
+ /*eslint-disable mocha-cleanup/asserts-limit */
+ describe('#map', function () {
var json = {
items: [
@@ -148,6 +149,17 @@ describe('App.alertDefinitionsMapper', function () {
"scope" : "HOST",
"service_name" : "YARN",
"source" : {
+ "parameters" : [
+ {
+ "name" : "connection.timeout",
+ "display_name" : "Connection Timeout",
+ "units" : "seconds",
+ "value" : 5.0,
+ "description" : "The maximum time before this alert is considered to be CRITICAL",
+ "type" : "NUMERIC",
+ "threshold" : "CRITICAL"
+ }
+ ],
"path" : "HDP/2.0.6/services/YARN/package/files/alert_nodemanager_health.py",
"type" : "SCRIPT"
}
@@ -187,7 +199,7 @@ describe('App.alertDefinitionsMapper', function () {
App.alertDefinitionsMapper.setProperties({
'model': {},
-
+ 'parameterModel': {},
'reportModel': {},
'metricsSourceModel': {},
'metricsUriModel': {}
@@ -352,7 +364,7 @@ describe('App.alertDefinitionsMapper', function () {
});
- it('should parse SCRIPT alertDefinitions', function () {
+ describe('should parse SCRIPT alertDefinitions', function () {
var data = {items: [json.items[3]]},
expected = [
@@ -370,9 +382,29 @@ describe('App.alertDefinitionsMapper', function () {
"location":"HDP/2.0.6/services/YARN/package/files/alert_nodemanager_health.py"
}
];
- App.alertDefinitionsMapper.map(data);
- testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
+ var expectedParameters = [{
+ "id": "4connection.timeout",
+ "name": "connection.timeout",
+ "display_name": "Connection Timeout",
+ "units": "seconds",
+ "value": 5,
+ "description": "The maximum time before this alert is considered to be CRITICAL",
+ "type": "NUMERIC",
+ "threshold": "CRITICAL"
+ }];
+
+ beforeEach(function () {
+ App.alertDefinitionsMapper.map(data);
+ });
+
+ it('should map definition', function () {
+ testHelpers.nestedExpect(expected, App.alertDefinitionsMapper.get('model.content'));
+ });
+
+ it('should map parameters', function () {
+ testHelpers.nestedExpect(expectedParameters, App.alertDefinitionsMapper.get('parameterModel.content'));
+ });
});
@@ -401,6 +433,7 @@ describe('App.alertDefinitionsMapper', function () {
});
+ /*eslint-disable mocha-cleanup/complexity-it */
it('should set groups from App.cache.previousAlertGroupsMap', function () {
App.cache.previousAlertGroupsMap = {
@@ -421,6 +454,7 @@ describe('App.alertDefinitionsMapper', function () {
});
+ /*eslint-enable mocha-cleanup/complexity-it */
describe('should delete not existing definitions', function () {
@@ -450,5 +484,6 @@ describe('App.alertDefinitionsMapper', function () {
});
});
+ /*eslint-enable mocha-cleanup/asserts-limit */
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/6d9e0599/ambari-web/test/models/alerts/alert_config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/alerts/alert_config_test.js b/ambari-web/test/models/alerts/alert_config_test.js
index 236fcde..4b788f8 100644
--- a/ambari-web/test/models/alerts/alert_config_test.js
+++ b/ambari-web/test/models/alerts/alert_config_test.js
@@ -24,6 +24,106 @@ var model;
describe('App.AlertConfigProperties', function () {
+ describe('Parameter', function () {
+
+ function getModel() {
+ return App.AlertConfigProperties.Parameter.create();
+ }
+
+ App.TestAliases.testAsComputedAlias(getModel(), 'badge', 'threshold');
+
+ });
+
+ describe('App.AlertConfigProperties.Parameters', function () {
+
+ describe('StringMixin', function () {
+
+ var obj;
+
+ beforeEach(function () {
+ obj = App.AlertConfigProperties.Parameter.create(App.AlertConfigProperties.Parameters.StringMixin, {});
+ });
+
+ describe('#isValid', function () {
+ Em.A([
+ {value: '', expected: false},
+ {value: '\t', expected: false},
+ {value: ' ', expected: false},
+ {value: '\n', expected: false},
+ {value: '\r', expected: false},
+ {value: 'some not empty string', expected: true}
+ ]).forEach(function (test) {
+ it('value: ' + JSON.stringify(test.value) + ' ;result - ' + test.expected, function () {
+ obj.set('value', test.value);
+ expect(obj.get('isValid')).to.be.equal(test.expected);
+ });
+ });
+ });
+
+ });
+
+ describe('NumericMixin', function () {
+
+ var obj;
+
+ beforeEach(function () {
+ obj = App.AlertConfigProperties.Parameter.create(App.AlertConfigProperties.Parameters.NumericMixin, {});
+ });
+
+ describe('#isValid', function () {
+ Em.A([
+ {value: '', expected: false},
+ {value: 'abc', expected: false},
+ {value: 'g1', expected: false},
+ {value: '1g', expected: false},
+ {value: '123', expected: true},
+ {value: '123.8', expected: true},
+ {value: 123, expected: true},
+ {value: 123.8, expected: true},
+ ]).forEach(function (test) {
+ it('value: ' + JSON.stringify(test.value) + ' ;result - ' + test.expected, function () {
+ obj.set('value', test.value);
+ expect(obj.get('isValid')).to.be.equal(test.expected);
+ });
+ });
+ });
+
+ });
+
+ describe('PercentageMixin', function () {
+
+ var obj;
+
+ beforeEach(function () {
+ obj = App.AlertConfigProperties.Parameter.create(App.AlertConfigProperties.Parameters.PercentageMixin, {});
+ });
+
+ describe('#isValid', function () {
+ Em.A([
+ {value: '', expected: false},
+ {value: 'abc', expected: false},
+ {value: 'g1', expected: false},
+ {value: '1g', expected: false},
+ {value: '123', expected: false},
+ {value: '23', expected: true},
+ {value: '123.8', expected: false},
+ {value: '5.8', expected: true},
+ {value: 123, expected: false},
+ {value: 23, expected: true},
+ {value: 123.8, expected: false},
+ {value: 5.8, expected: true}
+ ]).forEach(function (test) {
+ it('value: ' + JSON.stringify(test.value) + ' ;result - ' + test.expected, function () {
+ obj.set('value', test.value);
+ expect(obj.get('isValid')).to.be.equal(test.expected);
+ });
+ });
+ });
+
+ });
+
+ });
+
describe('Threshold', function () {
beforeEach(function () {