fable 3.0.113 → 3.0.114
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fable",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.114",
|
|
4
|
+
"description": "Anentity behavior management and API bundling library.",
|
|
5
5
|
"main": "source/Fable.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "node source/Fable.js",
|
|
@@ -254,7 +254,7 @@ class DataFormat extends libFableServiceProviderBase
|
|
|
254
254
|
* @param {*} pValue
|
|
255
255
|
* @returns {string}
|
|
256
256
|
*/
|
|
257
|
-
formatterDollars (pValue)
|
|
257
|
+
formatterDollars (pValue, pPrecision, pRoundingMethod)
|
|
258
258
|
{
|
|
259
259
|
if (isNaN(pValue))
|
|
260
260
|
{
|
|
@@ -266,23 +266,9 @@ class DataFormat extends libFableServiceProviderBase
|
|
|
266
266
|
return this._Value_NaN_Currency;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
let tmpDollarAmountArbitrary = this.fable.
|
|
270
|
-
let
|
|
271
|
-
|
|
272
|
-
if (isNaN(tmpDollarAmount))
|
|
273
|
-
{
|
|
274
|
-
// Try again and see if what was passed in was a dollars string.
|
|
275
|
-
if (typeof(pValue) == 'string')
|
|
276
|
-
{
|
|
277
|
-
// TODO: Better rounding function? This is a hack to get rid of the currency symbol and commas.
|
|
278
|
-
tmpDollarAmount = parseFloat(pValue.replace(this._Value_MoneySign_Currency,'').replace(this._Regex_formatterDollarsRemoveCommas,'')).toFixed(2);
|
|
279
|
-
}
|
|
280
|
-
// If we didn't get a number, return the "not a number" string.
|
|
281
|
-
if (isNaN(tmpDollarAmount))
|
|
282
|
-
{
|
|
283
|
-
return this._Value_NaN_Currency;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
269
|
+
let tmpDollarAmountArbitrary = this.fable.Math.parsePrecise(pValue);
|
|
270
|
+
let tmpPrecision = (typeof(pPrecision) == 'undefined') ? 2 : pPrecision;
|
|
271
|
+
let tmpDollarAmount = this.fable.Math.toFixedPrecise(tmpDollarAmountArbitrary, tmpPrecision, pRoundingMethod);
|
|
286
272
|
|
|
287
273
|
// TODO: Get locale data and use that for this stuff.
|
|
288
274
|
return `$${this.formatterAddCommasToNumber(tmpDollarAmount)}`;
|
|
@@ -3,7 +3,7 @@ const libFableServiceBase = require('fable-serviceproviderbase');
|
|
|
3
3
|
/**
|
|
4
4
|
* Arbitrary Precision Math Operations
|
|
5
5
|
* @author Steven Velozo <steven@velozo.com>
|
|
6
|
-
* @description Simple functions that perform arbitrary precision math operations and return string resultant values.
|
|
6
|
+
* @description Simple functions that perform arbitrary precision math operations and return string resultant values. Wraps big.js
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
class FableServiceMath extends libFableServiceBase
|
|
@@ -15,22 +15,78 @@ class FableServiceMath extends libFableServiceBase
|
|
|
15
15
|
this.serviceType = 'Math';
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
Rounding Methods:
|
|
21
|
+
|
|
22
|
+
Property Value BigDecimal Equiv Description
|
|
23
|
+
---------- ----- ---------------- -----------
|
|
24
|
+
roundDown 0 ROUND_DOWN Rounds towards zero. (_I.e. truncate, no rounding._)
|
|
25
|
+
roundHalfUp 1 ROUND_HALF_UP Rounds towards nearest neighbour. (_If equidistant, rounds away from zero._)
|
|
26
|
+
roundHalfEven 2 ROUND_HALF_EVEN Rounds towards nearest neighbour. (_If equidistant, rounds towards even neighbour._)
|
|
27
|
+
roundUp 3 ROUND_UP Rounds positively away from zero. (_Always round up._)
|
|
28
|
+
*/
|
|
29
|
+
get roundDown() { return this.fable.Utility.bigNumber.roundDown; }
|
|
30
|
+
get roundHalfUp() { return this.fable.Utility.bigNumber.roundHalfUp; }
|
|
31
|
+
get roundHalfEven() { return this.fable.Utility.bigNumber.roundHalfEven; }
|
|
32
|
+
get roundUp() { return this.fable.Utility.bigNumber.roundUp; }
|
|
33
|
+
|
|
34
|
+
parsePrecise(pValue, pNonNumberValue)
|
|
19
35
|
{
|
|
20
|
-
let tmpNumber
|
|
36
|
+
let tmpNumber;
|
|
21
37
|
|
|
22
38
|
try
|
|
23
39
|
{
|
|
24
|
-
|
|
40
|
+
tmpNumber = new this.fable.Utility.bigNumber(pValue);
|
|
25
41
|
}
|
|
26
42
|
catch(pError)
|
|
27
43
|
{
|
|
28
|
-
|
|
44
|
+
this.log.warn(`Error parsing number (type ${typeof(pValue)}): ${pError}`);
|
|
45
|
+
tmpNumber = (typeof(pNonNumberValue) === 'undefined') ? "0.0" : pNonNumberValue;
|
|
29
46
|
}
|
|
30
47
|
|
|
31
48
|
return tmpNumber.toString();
|
|
32
49
|
}
|
|
33
50
|
|
|
51
|
+
percentagePrecise(pIs, pOf)
|
|
52
|
+
{
|
|
53
|
+
let tmpLeftValue = isNaN(pIs) ? 0 : pIs;
|
|
54
|
+
let tmpRightValue = isNaN(pOf) ? 0 : pOf;
|
|
55
|
+
|
|
56
|
+
if (tmpRightValue == 0)
|
|
57
|
+
{
|
|
58
|
+
return '0';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
|
|
62
|
+
let tmpResult = tmpLeftArbitraryValue.div(tmpRightValue);
|
|
63
|
+
tmpResult = tmpResult.times(100);
|
|
64
|
+
return tmpResult.toString();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
roundPrecise(pValue, pDecimals, pRoundingMethod)
|
|
68
|
+
{
|
|
69
|
+
let tmpValue = isNaN(pValue) ? 0 : pValue;
|
|
70
|
+
let tmpDecimals = isNaN(pDecimals) ? 0 : pDecimals;
|
|
71
|
+
let tmpRoundingMethod = (typeof(pRoundingMethod) === 'undefined') ? this.roundHalfUp : pRoundingMethod;
|
|
72
|
+
|
|
73
|
+
let tmpArbitraryValue = new this.fable.Utility.bigNumber(tmpValue);
|
|
74
|
+
let tmpResult = tmpArbitraryValue.round(tmpDecimals, tmpRoundingMethod);
|
|
75
|
+
return tmpResult.toString();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
toFixedPrecise(pValue, pDecimals, pRoundingMethod)
|
|
79
|
+
{
|
|
80
|
+
let tmpValue = isNaN(pValue) ? 0 : pValue;
|
|
81
|
+
let tmpDecimals = isNaN(pDecimals) ? 0 : pDecimals;
|
|
82
|
+
let tmpRoundingMethod = (typeof(pRoundingMethod) === 'undefined') ? this.roundHalfUp : pRoundingMethod;
|
|
83
|
+
|
|
84
|
+
let tmpArbitraryValue = new this.fable.Utility.bigNumber(tmpValue);
|
|
85
|
+
let tmpResult = tmpArbitraryValue.toFixed(tmpDecimals, tmpRoundingMethod);
|
|
86
|
+
|
|
87
|
+
return tmpResult.toString();
|
|
88
|
+
}
|
|
89
|
+
|
|
34
90
|
addPrecise(pLeftValue, pRightValue)
|
|
35
91
|
{
|
|
36
92
|
let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
|
|
@@ -70,22 +126,6 @@ class FableServiceMath extends libFableServiceBase
|
|
|
70
126
|
let tmpResult = tmpLeftArbitraryValue.div(tmpRightValue);
|
|
71
127
|
return tmpResult.toString();
|
|
72
128
|
}
|
|
73
|
-
|
|
74
|
-
percentagePrecise(pIs, pOf)
|
|
75
|
-
{
|
|
76
|
-
let tmpLeftValue = isNaN(pIs) ? 0 : pIs;
|
|
77
|
-
let tmpRightValue = isNaN(pOf) ? 0 : pOf;
|
|
78
|
-
|
|
79
|
-
if (tmpRightValue == 0)
|
|
80
|
-
{
|
|
81
|
-
return '0';
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
|
|
85
|
-
let tmpResult = tmpLeftArbitraryValue.div(tmpRightValue);
|
|
86
|
-
tmpResult = tmpResult.times(100);
|
|
87
|
-
return tmpResult.toString();
|
|
88
|
-
}
|
|
89
129
|
}
|
|
90
130
|
|
|
91
131
|
module.exports = FableServiceMath;
|
package/test/Math_test.js
CHANGED
|
@@ -38,6 +38,11 @@ suite
|
|
|
38
38
|
Expect(testFable.Math.multiplyPrecise(1, 1)).to.equal('1');
|
|
39
39
|
Expect(testFable.Math.dividePrecise(1, 1)).to.equal('1');
|
|
40
40
|
Expect(testFable.Math.percentagePrecise(1, 1)).to.equal('100');
|
|
41
|
+
Expect(testFable.Math.percentagePrecise(1, 0)).to.equal('0');
|
|
42
|
+
Expect(testFable.Math.percentagePrecise(0, 1)).to.equal('0');
|
|
43
|
+
Expect(testFable.Math.percentagePrecise(0, 0)).to.equal('0');
|
|
44
|
+
Expect(testFable.Math.percentagePrecise(500, 100)).to.equal('500');
|
|
45
|
+
Expect(testFable.Math.percentagePrecise(100, 500)).to.equal('20');
|
|
41
46
|
|
|
42
47
|
return fDone();
|
|
43
48
|
}
|
|
@@ -57,6 +62,79 @@ suite
|
|
|
57
62
|
return fDone();
|
|
58
63
|
}
|
|
59
64
|
);
|
|
65
|
+
|
|
66
|
+
test
|
|
67
|
+
(
|
|
68
|
+
'Round Numbers',
|
|
69
|
+
function(fDone)
|
|
70
|
+
{
|
|
71
|
+
let testFable = new libFable();
|
|
72
|
+
|
|
73
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 2)).to.equal('1.12');
|
|
74
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 4)).to.equal('1.1235');
|
|
75
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 8)).to.equal('1.12345679');
|
|
76
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 10)).to.equal('1.123456789');
|
|
77
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 12)).to.equal('1.123456789');
|
|
78
|
+
Expect(testFable.Math.roundPrecise(1.123456789, 14)).to.equal('1.123456789');
|
|
79
|
+
|
|
80
|
+
Expect(testFable.Math.roundPrecise(undefined, 2)).to.equal('0');
|
|
81
|
+
|
|
82
|
+
try
|
|
83
|
+
{
|
|
84
|
+
testFable.Math.roundPrecise(null, 2, testFable.Math.roundHalfUp)
|
|
85
|
+
}
|
|
86
|
+
catch(pError)
|
|
87
|
+
{
|
|
88
|
+
Expect(pError).to.be.an.instanceof(Error);
|
|
89
|
+
Expect(pError.message).to.equal('[big.js] Invalid number');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71263219214217312', 15, testFable.Math.roundDown)).to.equal('867530999999999.712632192142173');
|
|
93
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundUp)).to.equal('867530999999999.71264');
|
|
94
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfUp)).to.equal('867530999999999.71264');
|
|
95
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfEven)).to.equal('867530999999999.71264');
|
|
96
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71663519214217312', 2, testFable.Math.roundHalfEven)).to.equal('867530999999999.72');
|
|
97
|
+
Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 4, testFable.Math.roundHalfEven)).to.equal('867530999999999.7126');
|
|
98
|
+
|
|
99
|
+
return fDone();
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
test
|
|
103
|
+
(
|
|
104
|
+
'Cast To Fixed Numbers',
|
|
105
|
+
function(fDone)
|
|
106
|
+
{
|
|
107
|
+
let testFable = new libFable();
|
|
108
|
+
|
|
109
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 2)).to.equal('1.12');
|
|
110
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 4)).to.equal('1.1235');
|
|
111
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 8)).to.equal('1.12345679');
|
|
112
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 10)).to.equal('1.1234567890');
|
|
113
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 12)).to.equal('1.123456789000');
|
|
114
|
+
Expect(testFable.Math.toFixedPrecise(1.123456789, 14)).to.equal('1.12345678900000');
|
|
115
|
+
|
|
116
|
+
Expect(testFable.Math.toFixedPrecise(undefined, 2)).to.equal('0.00');
|
|
117
|
+
|
|
118
|
+
try
|
|
119
|
+
{
|
|
120
|
+
testFable.Math.toFixedPrecise(null, 2, testFable.Math.roundHalfUp)
|
|
121
|
+
}
|
|
122
|
+
catch(pError)
|
|
123
|
+
{
|
|
124
|
+
Expect(pError).to.be.an.instanceof(Error);
|
|
125
|
+
Expect(pError.message).to.equal('[big.js] Invalid number');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71263219214217312', 15, testFable.Math.roundDown)).to.equal('867530999999999.712632192142173');
|
|
129
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundUp)).to.equal('867530999999999.71264');
|
|
130
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfUp)).to.equal('867530999999999.71264');
|
|
131
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfEven)).to.equal('867530999999999.71264');
|
|
132
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71663519214217312', 2, testFable.Math.roundHalfEven)).to.equal('867530999999999.72');
|
|
133
|
+
Expect(testFable.Math.toFixedPrecise('867530999999999.71', 4, testFable.Math.roundHalfEven)).to.equal('867530999999999.7100');
|
|
134
|
+
|
|
135
|
+
return fDone();
|
|
136
|
+
}
|
|
137
|
+
);
|
|
60
138
|
}
|
|
61
139
|
);
|
|
62
140
|
}
|