mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 20:25:48 +00:00
[FIX] amount human parsing for hex with amount
There were cases where the currency and integer were incorrectly matched. By separating out the regex for hex formatted Amount makes it easier to deal with these cases and fixes the issue.
This commit is contained in:
@@ -598,30 +598,48 @@ Amount.prototype.invert = function() {
|
||||
* The regular expression below matches above cases, broken down for better understanding:
|
||||
*
|
||||
* ^\s* // start with any amount of whitespace
|
||||
* ([a-zA-Z]{3}|[0-9]{3}) // either 3 letter alphabetic currency-code or 3 digit numeric currency-code. See ISO 4217
|
||||
* ([A-z]{3}|[0-9]{3}) // either 3 letter alphabetic currency-code or 3 digit numeric currency-code. See ISO 4217
|
||||
* \s* // any amount of whitespace
|
||||
* (-)? // optional dash
|
||||
* (\d+) // 1 or more digits
|
||||
* (?:\.(\d*))? // optional . character with any amount of digits
|
||||
* \s* // any amount of whitespace
|
||||
* ([a-f0-9]{40}|[a-z0-9]{3})? // optional 40 character hex string OR 3 letters
|
||||
* ([A-z]{3}|[0-9]{3})? // either 3 letter alphabetic currency-code or 3 digit numeric currency-code. See ISO 4217
|
||||
* \s* // any amount of whitespace
|
||||
* $ // end of string
|
||||
*
|
||||
*/
|
||||
Amount.human_RE = /^\s*([a-z]{3}|[0-9]{3})?\s*(-)?(\d+)(?:\.(\d*))?\s*([a-f0-9]{40}|[a-z0-9]{3})?\s*$/i;
|
||||
Amount.human_RE_hex = /^\s*(-)?(\d+)(?:\.(\d*))?\s*([a-fA-F0-9]{40})\s*$/;
|
||||
Amount.human_RE = /^\s*([A-z]{3}|[0-9]{3})?\s*(-)?(\d+)(?:\.(\d*))?\s*([A-z]{3}|[0-9]{3})?\s*$/;
|
||||
|
||||
Amount.prototype.parse_human = function(j, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var m = String(j).match(Amount.human_RE);
|
||||
var integer;
|
||||
var fraction;
|
||||
var currency;
|
||||
var precision = null;
|
||||
|
||||
if (m) {
|
||||
var currency = m[5] || m[1] || 'XRP';
|
||||
var integer = m[5] && m[1] ? m[1] + '' + m[3] : (m[3] || '0');
|
||||
var fraction = m[4] || '';
|
||||
var precision = null;
|
||||
// first check if it's a hex formatted currency
|
||||
var matches = String(j).match(Amount.human_RE_hex);
|
||||
if (matches && matches.length === 5 && matches[4]) {
|
||||
integer = matches[2];
|
||||
fraction = matches[3] || '';
|
||||
currency = matches[4];
|
||||
this._is_negative = Boolean(matches[1]);
|
||||
}
|
||||
|
||||
if (integer === void(0) && currency === void(0)) {
|
||||
var m = String(j).match(Amount.human_RE);
|
||||
if (m) {
|
||||
currency = m[5] || m[1] || 'XRP';
|
||||
integer = m[5] && m[1] ? m[1] + '' + m[3] : (m[3] || '0');
|
||||
fraction = m[4] || '';
|
||||
this._is_negative = Boolean(m[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (integer) {
|
||||
currency = currency.toUpperCase();
|
||||
|
||||
this._value = new BigInteger(integer);
|
||||
@@ -648,8 +666,6 @@ Amount.prototype.parse_human = function(j, opts) {
|
||||
this.canonicalize();
|
||||
}
|
||||
|
||||
this._is_negative = !!m[2];
|
||||
|
||||
// Apply interest/demurrage
|
||||
if (opts.reference_date && this._currency.has_interest()) {
|
||||
var interest = this._currency.get_interest_at(opts.reference_date);
|
||||
@@ -1155,7 +1171,7 @@ Amount.prototype.to_json = function() {
|
||||
} else {
|
||||
var amount_json = {
|
||||
value : this.to_text(),
|
||||
currency : this._currency.to_json()
|
||||
currency : this._currency.has_interest() ? this._currency.to_hex() : this._currency.to_json()
|
||||
};
|
||||
if (this._issuer.is_valid()) {
|
||||
amount_json.issuer = this._issuer.to_json();
|
||||
|
||||
@@ -35,6 +35,30 @@ describe('Amount', function() {
|
||||
it('12345.6789 XAU', function() {
|
||||
assert.strictEqual(Amount.from_human("12345.6789 XAU").to_text_full(), '12345.6789/XAU/NaN');
|
||||
});
|
||||
it('12345.6789 015841551A748AD2C1F76FF6ECB0CCCD00000000', function() {
|
||||
assert.strictEqual(Amount.from_human("12345.6789 015841551A748AD2C1F76FF6ECB0CCCD00000000").to_text_full(), '12345.6789/XAU (-0.5%pa)/NaN');
|
||||
});
|
||||
it('12345.6789 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("12345.6789 0000000000000000000000005553440000000000").to_text_full(), '12345.6789/USD/NaN');
|
||||
});
|
||||
it('10 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("10 0000000000000000000000005553440000000000").to_text_full(), '10/USD/NaN');
|
||||
});
|
||||
it('100 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("100 0000000000000000000000005553440000000000").to_text_full(), '100/USD/NaN');
|
||||
});
|
||||
it('1000 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("1000 0000000000000000000000005553440000000000").to_text_full(), '1000/USD/NaN');
|
||||
});
|
||||
it('-100 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("-100 0000000000000000000000005553440000000000").to_text_full(), '-100/USD/NaN');
|
||||
});
|
||||
it('-1000 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("-1000 0000000000000000000000005553440000000000").to_text_full(), '-1000/USD/NaN');
|
||||
});
|
||||
it('-1000.001 0000000000000000000000005553440000000000', function() {
|
||||
assert.strictEqual(Amount.from_human("-1000.001 0000000000000000000000005553440000000000").to_text_full(), '-1000.001/USD/NaN');
|
||||
});
|
||||
it('XAU 12345.6789', function() {
|
||||
assert.strictEqual(Amount.from_human("XAU 12345.6789").to_text_full(), '12345.6789/XAU/NaN');
|
||||
});
|
||||
@@ -190,6 +214,23 @@ describe('Amount', function() {
|
||||
assert.strictEqual('0/XRP/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full());
|
||||
});
|
||||
});
|
||||
describe('Amount to_json', function() {
|
||||
it('10 USD', function() {
|
||||
var amount = Amount.from_human("10 USD").to_json();
|
||||
assert.strictEqual("10", amount.value);
|
||||
assert.strictEqual("USD", amount.currency);
|
||||
});
|
||||
it('10 0000000000000000000000005553440000000000', function() {
|
||||
var amount = Amount.from_human("10 0000000000000000000000005553440000000000").to_json();
|
||||
assert.strictEqual("10", amount.value);
|
||||
assert.strictEqual("USD", amount.currency);
|
||||
});
|
||||
it('10 015841551A748AD2C1F76FF6ECB0CCCD00000000', function() {
|
||||
var amount = Amount.from_human("10 015841551A748AD2C1F76FF6ECB0CCCD00000000").to_json();
|
||||
assert.strictEqual("10", amount.value);
|
||||
assert.strictEqual("015841551A748AD2C1F76FF6ECB0CCCD00000000", amount.currency);
|
||||
});
|
||||
});
|
||||
describe('Amount operations', function() {
|
||||
it('Negate native 123', function () {
|
||||
assert.strictEqual('-0.000123/XRP', Amount.from_json('123').negate().to_text_full());
|
||||
|
||||
Reference in New Issue
Block a user