diff --git a/CHANGELOG.md b/CHANGELOG.md index 09c46c8..d4789d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ Changelog * Added an implementation of the `allocate()` function from Fowler's Enterprise Design Patterns. * Fixed parsing string numbers without a fractional part. +* Added `toSource()` and `fromSource()` methods to easily get access to the + underlying bigint. +* `Money.value` is now private. 0.2.0 (2018-12-12) diff --git a/readme.md b/readme.md index d543825..fc8d319 100644 --- a/readme.md +++ b/readme.md @@ -162,12 +162,6 @@ number of digits you are interested in. For USD and most currencies this is 2. It's required to pass this argument because the Money object can't guess the desired precision. -### TODO - -1. toSource (to get the underlying bigint value) -2. fromSource (to create a new Money object from a high-precision - bigint value) - Why is this library needed? --------------------------- diff --git a/src/money.ts b/src/money.ts index 013e989..6a8cba7 100644 --- a/src/money.ts +++ b/src/money.ts @@ -10,7 +10,7 @@ import { export class Money { currency: string; - value: bigint; + private value: bigint; constructor(value: number | bigint | string, currency: string) { @@ -40,8 +40,7 @@ export class Money { } const addVal = moneyValueToBigInt(val); - const r = new Money(0, this.currency); - r.value = addVal + this.value; + const r = Money.fromSource(addVal + this.value, this.currency); return r; } @@ -53,9 +52,7 @@ export class Money { } const subVal = moneyValueToBigInt(val); - const r = new Money(0, this.currency); - r.value = this.value - subVal; - return r; + return Money.fromSource(this.value - subVal, this.currency); } @@ -75,9 +72,10 @@ export class Money { // Converting the dividor. const val2 = moneyValueToBigInt(val); - const result = new Money(0, this.currency); - result.value = nearestEvenDivide(val1, val2); - return result; + return Money.fromSource( + nearestEvenDivide(val1, val2), + this.currency + ); } @@ -91,9 +89,10 @@ export class Money { // Converting the dividor. const resultBig = valBig * this.value; - const result = new Money(0, this.currency); - result.value = nearestEvenDivide(resultBig, PRECISION_M); - return result; + return Money.fromSource( + nearestEvenDivide(resultBig, PRECISION_M), + this.currency + ); } @@ -163,12 +162,38 @@ export class Money { return result.map( item => { - const m = new Money(0, this.currency); - m.value = item * precisionRounder; - return m; + return Money.fromSource( + item * precisionRounder, + this.currency + ); }); } + /** + * Returns the underlying bigint value. + * + * This is the current value of the object, multiplied by 10 ** 12. + */ + toSource(): bigint { + + return this.value; + + } + + /** + * A factory function to construct a Money object a 'source' value. + * + * The source value is just the underlying bigint used in the Money + * class and can be obtained by calling Money.getSource(). + */ + static fromSource(val: bigint, currency: string): Money { + + const m = new Money(0, currency); + m.value = val; + + return m; + + } } diff --git a/src/util.ts b/src/util.ts index c4f88c4..c0ab00a 100644 --- a/src/util.ts +++ b/src/util.ts @@ -19,7 +19,7 @@ export const PRECISION_M = 10n ** PRECISION; export function moneyValueToBigInt(input: Money | string | number | bigint): bigint { if (input instanceof Money) { - return input.value; + return input.toSource(); } switch (typeof input) { diff --git a/test/money.ts b/test/money.ts index 1c6dbab..3043b9f 100644 --- a/test/money.ts +++ b/test/money.ts @@ -317,11 +317,22 @@ describe('Money class', () => { expect(result.map( item => item.toFixed(cas[2]))).to.eql(cas[3]); // Double-check. Numbers must exactly add up to the source value - expect(result.reduce( (acc, cur) => acc + cur.value, 0n)).to.equal(x.value); + expect(result.reduce( (acc, cur) => acc + cur.toSource(), 0n)).to.equal(x.toSource()); }); } }); + describe('toSource', () => { + + it('should return the underlying source bigint value', () => { + + const m = new Money(1, 'USD'); + expect(m.toSource()).to.equal(1000000000000n); + + }); + + }); + });