@dhis2/analytics 21.9.0 → 21.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/build/cjs/components/FileMenu/FileMenu.js +2 -3
- package/build/cjs/modules/pivotTable/PivotTableEngine.js +9 -28
- package/build/cjs/modules/pivotTable/__tests__/addToTotalIfNumber.js +72 -0
- package/build/cjs/modules/pivotTable/addToTotalIfNumber.js +10 -0
- package/build/es/components/FileMenu/FileMenu.js +2 -3
- package/build/es/modules/pivotTable/PivotTableEngine.js +8 -28
- package/build/es/modules/pivotTable/__tests__/addToTotalIfNumber.js +69 -0
- package/build/es/modules/pivotTable/addToTotalIfNumber.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [21.10.0](https://github.com/dhis2/analytics/compare/v21.9.1...v21.10.0) (2024-04-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* disable Save button when onSave not passed (TECH-1013) ([#1652](https://github.com/dhis2/analytics/issues/1652)) ([b8e17fb](https://github.com/dhis2/analytics/commit/b8e17fba1243188ff28b0813e26528f2b1810553))
|
|
7
|
+
|
|
8
|
+
## [21.9.1](https://github.com/dhis2/analytics/compare/v21.9.0...v21.9.1) (2023-10-05)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* avoid undefined in totals DHIS2-14511 ([#1552](https://github.com/dhis2/analytics/issues/1552)) ([#1585](https://github.com/dhis2/analytics/issues/1585)) ([f2c1fd1](https://github.com/dhis2/analytics/commit/f2c1fd1807af875e0af0f49bc2027862863ade35))
|
|
14
|
+
|
|
1
15
|
# [21.9.0](https://github.com/dhis2/analytics/compare/v21.8.2...v21.9.0) (2023-03-02)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -193,9 +193,9 @@ const FileMenu = ({
|
|
|
193
193
|
}), /*#__PURE__*/_react.default.createElement(_ui.MenuItem, {
|
|
194
194
|
label: fileObject !== null && fileObject !== void 0 && fileObject.id ? _index.default.t('Save') : _index.default.t('Save…'),
|
|
195
195
|
icon: /*#__PURE__*/_react.default.createElement(_ui.IconSave24, {
|
|
196
|
-
color: !(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access = fileObject.access) !== null && _fileObject$access !== void 0 && _fileObject$access.update ?
|
|
196
|
+
color: !onSave || !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access = fileObject.access) !== null && _fileObject$access !== void 0 && _fileObject$access.update) ? iconInactiveColor : iconActiveColor
|
|
197
197
|
}),
|
|
198
|
-
disabled: !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access2 = fileObject.access) !== null && _fileObject$access2 !== void 0 && _fileObject$access2.update),
|
|
198
|
+
disabled: !onSave || !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access2 = fileObject.access) !== null && _fileObject$access2 !== void 0 && _fileObject$access2.update),
|
|
199
199
|
onClick: fileObject !== null && fileObject !== void 0 && fileObject.id ? () => {
|
|
200
200
|
toggleMenu();
|
|
201
201
|
onSave();
|
|
@@ -260,7 +260,6 @@ FileMenu.defaultProps = {
|
|
|
260
260
|
onNew: Function.prototype,
|
|
261
261
|
onOpen: Function.prototype,
|
|
262
262
|
onRename: Function.prototype,
|
|
263
|
-
onSave: Function.prototype,
|
|
264
263
|
onSaveAs: Function.prototype,
|
|
265
264
|
onTranslate: Function.prototype
|
|
266
265
|
};
|
|
@@ -11,6 +11,8 @@ var _predefinedDimensions = require("../predefinedDimensions.js");
|
|
|
11
11
|
|
|
12
12
|
var _AdaptiveClippingController = require("./AdaptiveClippingController.js");
|
|
13
13
|
|
|
14
|
+
var _addToTotalIfNumber = require("./addToTotalIfNumber.js");
|
|
15
|
+
|
|
14
16
|
var _parseValue = require("./parseValue.js");
|
|
15
17
|
|
|
16
18
|
var _pivotTableConstants = require("./pivotTableConstants.js");
|
|
@@ -611,10 +613,7 @@ class PivotTableEngine {
|
|
|
611
613
|
dataFields.forEach(field => {
|
|
612
614
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
613
615
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
614
|
-
|
|
615
|
-
if (value && !isNaN(value)) {
|
|
616
|
-
totalCell[field] = (totalCell[field] || 0) + value;
|
|
617
|
-
}
|
|
616
|
+
totalCell[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, totalCell[field]);
|
|
618
617
|
});
|
|
619
618
|
}
|
|
620
619
|
|
|
@@ -633,10 +632,7 @@ class PivotTableEngine {
|
|
|
633
632
|
dataFields.forEach(field => {
|
|
634
633
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
635
634
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
636
|
-
|
|
637
|
-
if (value && !isNaN(value)) {
|
|
638
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
639
|
-
}
|
|
635
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
640
636
|
});
|
|
641
637
|
|
|
642
638
|
if (totals.columnSubtotal) {
|
|
@@ -651,10 +647,7 @@ class PivotTableEngine {
|
|
|
651
647
|
dataFields.forEach(field => {
|
|
652
648
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
653
649
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
654
|
-
|
|
655
|
-
if (value && !isNaN(value)) {
|
|
656
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
657
|
-
}
|
|
650
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
658
651
|
});
|
|
659
652
|
}
|
|
660
653
|
|
|
@@ -670,10 +663,7 @@ class PivotTableEngine {
|
|
|
670
663
|
dataFields.forEach(field => {
|
|
671
664
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
672
665
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
673
|
-
|
|
674
|
-
if (value && !isNaN(value)) {
|
|
675
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
676
|
-
}
|
|
666
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
677
667
|
});
|
|
678
668
|
}
|
|
679
669
|
}
|
|
@@ -690,10 +680,7 @@ class PivotTableEngine {
|
|
|
690
680
|
dataFields.forEach(field => {
|
|
691
681
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
692
682
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
693
|
-
|
|
694
|
-
if (value && !isNaN(value)) {
|
|
695
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
696
|
-
}
|
|
683
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
697
684
|
});
|
|
698
685
|
|
|
699
686
|
if (totals.rowSubtotal) {
|
|
@@ -708,10 +695,7 @@ class PivotTableEngine {
|
|
|
708
695
|
dataFields.forEach(field => {
|
|
709
696
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
710
697
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
711
|
-
|
|
712
|
-
if (value && !isNaN(value)) {
|
|
713
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
714
|
-
}
|
|
698
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
715
699
|
});
|
|
716
700
|
}
|
|
717
701
|
|
|
@@ -727,10 +711,7 @@ class PivotTableEngine {
|
|
|
727
711
|
dataFields.forEach(field => {
|
|
728
712
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
729
713
|
const value = (0, _parseValue.parseValue)(dataRow[headerIndex]);
|
|
730
|
-
|
|
731
|
-
if (value && !isNaN(value)) {
|
|
732
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
733
|
-
}
|
|
714
|
+
percentageTotal[field] = (0, _addToTotalIfNumber.addToTotalIfNumber)(value, percentageTotal[field]);
|
|
734
715
|
});
|
|
735
716
|
}
|
|
736
717
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _addToTotalIfNumber = require("../addToTotalIfNumber.js");
|
|
4
|
+
|
|
5
|
+
const tests = [{
|
|
6
|
+
testName: 'negative value',
|
|
7
|
+
value: -1,
|
|
8
|
+
total: undefined,
|
|
9
|
+
expected: -1
|
|
10
|
+
}, {
|
|
11
|
+
testName: 'zero value',
|
|
12
|
+
value: 0,
|
|
13
|
+
total: undefined,
|
|
14
|
+
expected: 0
|
|
15
|
+
}, {
|
|
16
|
+
testName: 'positive value',
|
|
17
|
+
value: 1,
|
|
18
|
+
total: undefined,
|
|
19
|
+
expected: 1
|
|
20
|
+
}, {
|
|
21
|
+
testName: 'null value',
|
|
22
|
+
value: null,
|
|
23
|
+
total: undefined,
|
|
24
|
+
expected: undefined
|
|
25
|
+
}, {
|
|
26
|
+
testName: 'undefined value',
|
|
27
|
+
value: undefined,
|
|
28
|
+
total: undefined,
|
|
29
|
+
expected: undefined
|
|
30
|
+
}, {
|
|
31
|
+
testName: 'string value',
|
|
32
|
+
value: 'string',
|
|
33
|
+
total: undefined,
|
|
34
|
+
expected: undefined
|
|
35
|
+
}, {
|
|
36
|
+
testName: 'negative value with existing total',
|
|
37
|
+
value: -1,
|
|
38
|
+
total: 100,
|
|
39
|
+
expected: 99
|
|
40
|
+
}, {
|
|
41
|
+
testName: 'zero value with existing total',
|
|
42
|
+
value: 0,
|
|
43
|
+
total: 100,
|
|
44
|
+
expected: 100
|
|
45
|
+
}, {
|
|
46
|
+
testName: 'positive value with existing total',
|
|
47
|
+
value: 1,
|
|
48
|
+
total: 100,
|
|
49
|
+
expected: 101
|
|
50
|
+
}, {
|
|
51
|
+
testName: 'null value with existing total',
|
|
52
|
+
value: null,
|
|
53
|
+
total: 100,
|
|
54
|
+
expected: 100
|
|
55
|
+
}, {
|
|
56
|
+
testName: 'undefined value with existing total',
|
|
57
|
+
value: undefined,
|
|
58
|
+
total: 100,
|
|
59
|
+
expected: 100
|
|
60
|
+
}, {
|
|
61
|
+
testName: 'string value with existing total',
|
|
62
|
+
value: 'string',
|
|
63
|
+
total: 100,
|
|
64
|
+
expected: 100
|
|
65
|
+
}];
|
|
66
|
+
describe('addToTotalIfNumber', () => {
|
|
67
|
+
tests.forEach(t => {
|
|
68
|
+
it(t.testName, () => {
|
|
69
|
+
expect((0, _addToTotalIfNumber.addToTotalIfNumber)(t.value, t.total)).toEqual(t.expected);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addToTotalIfNumber = void 0;
|
|
7
|
+
|
|
8
|
+
const addToTotalIfNumber = (value, total) => typeof value === 'number' && Number.isFinite(value) ? (total !== null && total !== void 0 ? total : 0) + value : total;
|
|
9
|
+
|
|
10
|
+
exports.addToTotalIfNumber = addToTotalIfNumber;
|
|
@@ -167,9 +167,9 @@ export const FileMenu = ({
|
|
|
167
167
|
}), /*#__PURE__*/React.createElement(MenuItem, {
|
|
168
168
|
label: fileObject !== null && fileObject !== void 0 && fileObject.id ? i18n.t('Save') : i18n.t('Save…'),
|
|
169
169
|
icon: /*#__PURE__*/React.createElement(IconSave24, {
|
|
170
|
-
color: !(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access = fileObject.access) !== null && _fileObject$access !== void 0 && _fileObject$access.update ?
|
|
170
|
+
color: !onSave || !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access = fileObject.access) !== null && _fileObject$access !== void 0 && _fileObject$access.update) ? iconInactiveColor : iconActiveColor
|
|
171
171
|
}),
|
|
172
|
-
disabled: !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access2 = fileObject.access) !== null && _fileObject$access2 !== void 0 && _fileObject$access2.update),
|
|
172
|
+
disabled: !onSave || !(!(fileObject !== null && fileObject !== void 0 && fileObject.id) || fileObject !== null && fileObject !== void 0 && (_fileObject$access2 = fileObject.access) !== null && _fileObject$access2 !== void 0 && _fileObject$access2.update),
|
|
173
173
|
onClick: fileObject !== null && fileObject !== void 0 && fileObject.id ? () => {
|
|
174
174
|
toggleMenu();
|
|
175
175
|
onSave();
|
|
@@ -232,7 +232,6 @@ FileMenu.defaultProps = {
|
|
|
232
232
|
onNew: Function.prototype,
|
|
233
233
|
onOpen: Function.prototype,
|
|
234
234
|
onRename: Function.prototype,
|
|
235
|
-
onSave: Function.prototype,
|
|
236
235
|
onSaveAs: Function.prototype,
|
|
237
236
|
onTranslate: Function.prototype
|
|
238
237
|
};
|
|
@@ -3,6 +3,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
3
3
|
import times from 'lodash/times';
|
|
4
4
|
import { DIMENSION_ID_ORGUNIT } from '../predefinedDimensions.js';
|
|
5
5
|
import { AdaptiveClippingController } from './AdaptiveClippingController.js';
|
|
6
|
+
import { addToTotalIfNumber } from './addToTotalIfNumber.js';
|
|
6
7
|
import { parseValue } from './parseValue.js';
|
|
7
8
|
import { AGGREGATE_TYPE_NA, AGGREGATE_TYPE_AVERAGE, AGGREGATE_TYPE_SUM, CELL_TYPE_VALUE, CELL_TYPE_TOTAL, CELL_TYPE_SUBTOTAL, SORT_ORDER_ASCENDING, SORT_ORDER_DESCENDING, DISPLAY_DENSITY_PADDING_COMPACT, DISPLAY_DENSITY_PADDING_COMFORTABLE, DISPLAY_DENSITY_OPTION_COMFORTABLE, DISPLAY_DENSITY_OPTION_COMPACT, DISPLAY_DENSITY_OPTION_NORMAL, DISPLAY_DENSITY_PADDING_NORMAL, FONT_SIZE_OPTION_SMALL, FONT_SIZE_SMALL, FONT_SIZE_OPTION_LARGE, FONT_SIZE_LARGE, FONT_SIZE_OPTION_NORMAL, FONT_SIZE_NORMAL, VALUE_TYPE_NUMBER, NUMBER_TYPE_COLUMN_PERCENTAGE, NUMBER_TYPE_ROW_PERCENTAGE, DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGUNIT, DIMENSION_TYPE_PERIOD, VALUE_TYPE_TEXT, NUMBER_TYPE_VALUE } from './pivotTableConstants.js';
|
|
8
9
|
import { renderValue } from './renderValue.js';
|
|
@@ -596,10 +597,7 @@ export class PivotTableEngine {
|
|
|
596
597
|
dataFields.forEach(field => {
|
|
597
598
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
598
599
|
const value = parseValue(dataRow[headerIndex]);
|
|
599
|
-
|
|
600
|
-
if (value && !isNaN(value)) {
|
|
601
|
-
totalCell[field] = (totalCell[field] || 0) + value;
|
|
602
|
-
}
|
|
600
|
+
totalCell[field] = addToTotalIfNumber(value, totalCell[field]);
|
|
603
601
|
});
|
|
604
602
|
}
|
|
605
603
|
|
|
@@ -618,10 +616,7 @@ export class PivotTableEngine {
|
|
|
618
616
|
dataFields.forEach(field => {
|
|
619
617
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
620
618
|
const value = parseValue(dataRow[headerIndex]);
|
|
621
|
-
|
|
622
|
-
if (value && !isNaN(value)) {
|
|
623
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
624
|
-
}
|
|
619
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
625
620
|
});
|
|
626
621
|
|
|
627
622
|
if (totals.columnSubtotal) {
|
|
@@ -636,10 +631,7 @@ export class PivotTableEngine {
|
|
|
636
631
|
dataFields.forEach(field => {
|
|
637
632
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
638
633
|
const value = parseValue(dataRow[headerIndex]);
|
|
639
|
-
|
|
640
|
-
if (value && !isNaN(value)) {
|
|
641
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
642
|
-
}
|
|
634
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
643
635
|
});
|
|
644
636
|
}
|
|
645
637
|
|
|
@@ -655,10 +647,7 @@ export class PivotTableEngine {
|
|
|
655
647
|
dataFields.forEach(field => {
|
|
656
648
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
657
649
|
const value = parseValue(dataRow[headerIndex]);
|
|
658
|
-
|
|
659
|
-
if (value && !isNaN(value)) {
|
|
660
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
661
|
-
}
|
|
650
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
662
651
|
});
|
|
663
652
|
}
|
|
664
653
|
}
|
|
@@ -675,10 +664,7 @@ export class PivotTableEngine {
|
|
|
675
664
|
dataFields.forEach(field => {
|
|
676
665
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
677
666
|
const value = parseValue(dataRow[headerIndex]);
|
|
678
|
-
|
|
679
|
-
if (value && !isNaN(value)) {
|
|
680
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
681
|
-
}
|
|
667
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
682
668
|
});
|
|
683
669
|
|
|
684
670
|
if (totals.rowSubtotal) {
|
|
@@ -693,10 +679,7 @@ export class PivotTableEngine {
|
|
|
693
679
|
dataFields.forEach(field => {
|
|
694
680
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
695
681
|
const value = parseValue(dataRow[headerIndex]);
|
|
696
|
-
|
|
697
|
-
if (value && !isNaN(value)) {
|
|
698
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
699
|
-
}
|
|
682
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
700
683
|
});
|
|
701
684
|
}
|
|
702
685
|
|
|
@@ -712,10 +695,7 @@ export class PivotTableEngine {
|
|
|
712
695
|
dataFields.forEach(field => {
|
|
713
696
|
const headerIndex = this.dimensionLookup.dataHeaders[field];
|
|
714
697
|
const value = parseValue(dataRow[headerIndex]);
|
|
715
|
-
|
|
716
|
-
if (value && !isNaN(value)) {
|
|
717
|
-
percentageTotal[field] = (percentageTotal[field] || 0) + value;
|
|
718
|
-
}
|
|
698
|
+
percentageTotal[field] = addToTotalIfNumber(value, percentageTotal[field]);
|
|
719
699
|
});
|
|
720
700
|
}
|
|
721
701
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { addToTotalIfNumber } from '../addToTotalIfNumber.js';
|
|
2
|
+
const tests = [{
|
|
3
|
+
testName: 'negative value',
|
|
4
|
+
value: -1,
|
|
5
|
+
total: undefined,
|
|
6
|
+
expected: -1
|
|
7
|
+
}, {
|
|
8
|
+
testName: 'zero value',
|
|
9
|
+
value: 0,
|
|
10
|
+
total: undefined,
|
|
11
|
+
expected: 0
|
|
12
|
+
}, {
|
|
13
|
+
testName: 'positive value',
|
|
14
|
+
value: 1,
|
|
15
|
+
total: undefined,
|
|
16
|
+
expected: 1
|
|
17
|
+
}, {
|
|
18
|
+
testName: 'null value',
|
|
19
|
+
value: null,
|
|
20
|
+
total: undefined,
|
|
21
|
+
expected: undefined
|
|
22
|
+
}, {
|
|
23
|
+
testName: 'undefined value',
|
|
24
|
+
value: undefined,
|
|
25
|
+
total: undefined,
|
|
26
|
+
expected: undefined
|
|
27
|
+
}, {
|
|
28
|
+
testName: 'string value',
|
|
29
|
+
value: 'string',
|
|
30
|
+
total: undefined,
|
|
31
|
+
expected: undefined
|
|
32
|
+
}, {
|
|
33
|
+
testName: 'negative value with existing total',
|
|
34
|
+
value: -1,
|
|
35
|
+
total: 100,
|
|
36
|
+
expected: 99
|
|
37
|
+
}, {
|
|
38
|
+
testName: 'zero value with existing total',
|
|
39
|
+
value: 0,
|
|
40
|
+
total: 100,
|
|
41
|
+
expected: 100
|
|
42
|
+
}, {
|
|
43
|
+
testName: 'positive value with existing total',
|
|
44
|
+
value: 1,
|
|
45
|
+
total: 100,
|
|
46
|
+
expected: 101
|
|
47
|
+
}, {
|
|
48
|
+
testName: 'null value with existing total',
|
|
49
|
+
value: null,
|
|
50
|
+
total: 100,
|
|
51
|
+
expected: 100
|
|
52
|
+
}, {
|
|
53
|
+
testName: 'undefined value with existing total',
|
|
54
|
+
value: undefined,
|
|
55
|
+
total: 100,
|
|
56
|
+
expected: 100
|
|
57
|
+
}, {
|
|
58
|
+
testName: 'string value with existing total',
|
|
59
|
+
value: 'string',
|
|
60
|
+
total: 100,
|
|
61
|
+
expected: 100
|
|
62
|
+
}];
|
|
63
|
+
describe('addToTotalIfNumber', () => {
|
|
64
|
+
tests.forEach(t => {
|
|
65
|
+
it(t.testName, () => {
|
|
66
|
+
expect(addToTotalIfNumber(t.value, t.total)).toEqual(t.expected);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const addToTotalIfNumber = (value, total) => typeof value === 'number' && Number.isFinite(value) ? (total !== null && total !== void 0 ? total : 0) + value : total;
|