Skip to content

Commit

Permalink
Merge pull request #10 from evert/source
Browse files Browse the repository at this point in the history
Added 'fromSource' and 'toSource'.
  • Loading branch information
evert authored Dec 14, 2018
2 parents 5d2d61e + 24d636c commit 4518419
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 0 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?
---------------------------
Expand Down
55 changes: 40 additions & 15 deletions src/money.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
export class Money {

currency: string;
value: bigint;
private value: bigint;

constructor(value: number | bigint | string, currency: string) {

Expand Down Expand Up @@ -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;

}
Expand All @@ -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);

}

Expand All @@ -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
);

}

Expand All @@ -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
);


}
Expand Down Expand Up @@ -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;

}
}
2 changes: 1 addition & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 12 additions & 1 deletion test/money.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

});

});

});

0 comments on commit 4518419

Please sign in to comment.