fable 3.0.113 → 3.0.115

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.113",
4
- "description": "An entity behavior management and API bundling library.",
3
+ "version": "3.0.115",
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.Utility.bigNumber(pValue);
270
- let tmpDollarAmount = tmpDollarAmountArbitrary.toFixed(2);
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
- parsePrecise(pValue)
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 = "0.0";
36
+ let tmpNumber;
21
37
 
22
38
  try
23
39
  {
24
- tmpNumber = new this.fable.Utility.bigNumber(pValue);
40
+ tmpNumber = new this.fable.Utility.bigNumber(pValue);
25
41
  }
26
42
  catch(pError)
27
43
  {
28
- console.log(`Error parsing number (type ${typeof(pValue)}): ${pError}`);
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;
@@ -51,6 +107,16 @@ class FableServiceMath extends libFableServiceBase
51
107
  return tmpResult.toString();
52
108
  }
53
109
 
110
+ powerPrecise(pLeftValue, pRightValue)
111
+ {
112
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
113
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
114
+
115
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
116
+ let tmpResult = tmpLeftArbitraryValue.pow(tmpRightValue);
117
+ return tmpResult.toString();
118
+ }
119
+
54
120
  multiplyPrecise(pLeftValue, pRightValue)
55
121
  {
56
122
  let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
@@ -71,21 +137,78 @@ class FableServiceMath extends libFableServiceBase
71
137
  return tmpResult.toString();
72
138
  }
73
139
 
74
- percentagePrecise(pIs, pOf)
140
+ modPrecise(pLeftValue, pRightValue)
75
141
  {
76
- let tmpLeftValue = isNaN(pIs) ? 0 : pIs;
77
- let tmpRightValue = isNaN(pOf) ? 0 : pOf;
78
-
79
- if (tmpRightValue == 0)
80
- {
81
- return '0';
82
- }
142
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
143
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
83
144
 
84
145
  let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
85
- let tmpResult = tmpLeftArbitraryValue.div(tmpRightValue);
86
- tmpResult = tmpResult.times(100);
146
+ let tmpResult = tmpLeftArbitraryValue.mod(tmpRightValue);
147
+ return tmpResult.toString();
148
+ }
149
+
150
+ sqrtPrecise(pValue)
151
+ {
152
+ let tmpValue = isNaN(pValue) ? 0 : pValue;
153
+
154
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpValue);
155
+ let tmpResult = tmpLeftArbitraryValue.sqrt();
156
+ return tmpResult.toString();
157
+ }
158
+
159
+ absPrecise(pValue)
160
+ {
161
+ let tmpValue = isNaN(pValue) ? 0 : pValue;
162
+
163
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpValue);
164
+ let tmpResult = tmpLeftArbitraryValue.abs();
87
165
  return tmpResult.toString();
88
166
  }
167
+
168
+ comparePrecise(pLeftValue, pRightValue)
169
+ {
170
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
171
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
172
+
173
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
174
+ return tmpLeftArbitraryValue.cmp(tmpRightValue);
175
+ }
176
+
177
+ gtPrecise(pLeftValue, pRightValue)
178
+ {
179
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
180
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
181
+
182
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
183
+ return tmpLeftArbitraryValue.gt(tmpRightValue);
184
+ }
185
+
186
+ gtePrecise(pLeftValue, pRightValue)
187
+ {
188
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
189
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
190
+
191
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
192
+ return tmpLeftArbitraryValue.gte(tmpRightValue);
193
+ }
194
+
195
+ ltPrecise(pLeftValue, pRightValue)
196
+ {
197
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
198
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
199
+
200
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
201
+ return tmpLeftArbitraryValue.lt(tmpRightValue);
202
+ }
203
+
204
+ ltePrecise(pLeftValue, pRightValue)
205
+ {
206
+ let tmpLeftValue = isNaN(pLeftValue) ? 0 : pLeftValue;
207
+ let tmpRightValue = isNaN(pRightValue) ? 0 : pRightValue;
208
+
209
+ let tmpLeftArbitraryValue = new this.fable.Utility.bigNumber(tmpLeftValue);
210
+ return tmpLeftArbitraryValue.lt(tmpRightValue);
211
+ }
89
212
  }
90
213
 
91
214
  module.exports = FableServiceMath;
package/test/Math_test.js CHANGED
@@ -38,6 +38,27 @@ 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');
46
+
47
+ Expect(testFable.Math.powerPrecise(4,4)).to.equal('256');
48
+ Expect(testFable.Math.powerPrecise(5,2)).to.equal('25');
49
+ Expect(testFable.Math.powerPrecise(50,7)).to.equal('781250000000');
50
+ Expect(testFable.Math.sqrtPrecise(4)).to.equal('2');
51
+
52
+ Expect(testFable.Math.gtPrecise(4, 5)).to.equal(false);
53
+ Expect(testFable.Math.gtePrecise(1000, 5)).to.equal(true);
54
+ Expect(testFable.Math.ltePrecise(1000, 5)).to.equal(false);
55
+ Expect(testFable.Math.ltPrecise(4, 5)).to.equal(true);
56
+
57
+ Expect(testFable.Math.comparePrecise(4, 5)).to.equal(-1);
58
+
59
+ Expect(testFable.Math.modPrecise(4.939323, 4)).to.equal('0.939323');
60
+
61
+ Expect(testFable.Math.absPrecise('-492')).to.equal('492');
41
62
 
42
63
  return fDone();
43
64
  }
@@ -57,6 +78,79 @@ suite
57
78
  return fDone();
58
79
  }
59
80
  );
81
+
82
+ test
83
+ (
84
+ 'Round Numbers',
85
+ function(fDone)
86
+ {
87
+ let testFable = new libFable();
88
+
89
+ Expect(testFable.Math.roundPrecise(1.123456789, 2)).to.equal('1.12');
90
+ Expect(testFable.Math.roundPrecise(1.123456789, 4)).to.equal('1.1235');
91
+ Expect(testFable.Math.roundPrecise(1.123456789, 8)).to.equal('1.12345679');
92
+ Expect(testFable.Math.roundPrecise(1.123456789, 10)).to.equal('1.123456789');
93
+ Expect(testFable.Math.roundPrecise(1.123456789, 12)).to.equal('1.123456789');
94
+ Expect(testFable.Math.roundPrecise(1.123456789, 14)).to.equal('1.123456789');
95
+
96
+ Expect(testFable.Math.roundPrecise(undefined, 2)).to.equal('0');
97
+
98
+ try
99
+ {
100
+ testFable.Math.roundPrecise(null, 2, testFable.Math.roundHalfUp)
101
+ }
102
+ catch(pError)
103
+ {
104
+ Expect(pError).to.be.an.instanceof(Error);
105
+ Expect(pError.message).to.equal('[big.js] Invalid number');
106
+ }
107
+
108
+ Expect(testFable.Math.roundPrecise('867530999999999.71263219214217312', 15, testFable.Math.roundDown)).to.equal('867530999999999.712632192142173');
109
+ Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundUp)).to.equal('867530999999999.71264');
110
+ Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfUp)).to.equal('867530999999999.71264');
111
+ Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfEven)).to.equal('867530999999999.71264');
112
+ Expect(testFable.Math.roundPrecise('867530999999999.71663519214217312', 2, testFable.Math.roundHalfEven)).to.equal('867530999999999.72');
113
+ Expect(testFable.Math.roundPrecise('867530999999999.71263519214217312', 4, testFable.Math.roundHalfEven)).to.equal('867530999999999.7126');
114
+
115
+ return fDone();
116
+ }
117
+ );
118
+ test
119
+ (
120
+ 'Cast To Fixed Numbers',
121
+ function(fDone)
122
+ {
123
+ let testFable = new libFable();
124
+
125
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 2)).to.equal('1.12');
126
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 4)).to.equal('1.1235');
127
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 8)).to.equal('1.12345679');
128
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 10)).to.equal('1.1234567890');
129
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 12)).to.equal('1.123456789000');
130
+ Expect(testFable.Math.toFixedPrecise(1.123456789, 14)).to.equal('1.12345678900000');
131
+
132
+ Expect(testFable.Math.toFixedPrecise(undefined, 2)).to.equal('0.00');
133
+
134
+ try
135
+ {
136
+ testFable.Math.toFixedPrecise(null, 2, testFable.Math.roundHalfUp)
137
+ }
138
+ catch(pError)
139
+ {
140
+ Expect(pError).to.be.an.instanceof(Error);
141
+ Expect(pError.message).to.equal('[big.js] Invalid number');
142
+ }
143
+
144
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71263219214217312', 15, testFable.Math.roundDown)).to.equal('867530999999999.712632192142173');
145
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundUp)).to.equal('867530999999999.71264');
146
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfUp)).to.equal('867530999999999.71264');
147
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71263519214217312', 5, testFable.Math.roundHalfEven)).to.equal('867530999999999.71264');
148
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71663519214217312', 2, testFable.Math.roundHalfEven)).to.equal('867530999999999.72');
149
+ Expect(testFable.Math.toFixedPrecise('867530999999999.71', 4, testFable.Math.roundHalfEven)).to.equal('867530999999999.7100');
150
+
151
+ return fDone();
152
+ }
153
+ );
60
154
  }
61
155
  );
62
156
  }