diff --git a/README.md b/README.md index e7335c7..fe7aca0 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,23 @@ Default type: object, With option type: bigint ``` +**Exception**: if the number being parsed is a big decimal number, still returns it as BigNumber. + +```js +var JSONbig = require('json-bigint'); +var JSONbigNative = require('json-bigint')({ useNativeBigInt: true }); +var key = '{ "key": 993143214321423154315154321.1 }'; +console.log(`\n\nStoring the Number as a BigNumber!!`); +console.log('Input:', key); +var normal = JSONbig.parse(key); +var nativeBigInt = JSONbigNative.parse(key); +console.log( + 'Default type: %s, With option type: %s', + typeof normal.key, + typeof nativeBigInt.key +); +```` + #### options.alwaysParseAsBig, boolean, default false Specifies if all numbers should be stored as BigNumber. diff --git a/lib/parse.js b/lib/parse.js index bb4e5eb..2f03c3b 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -169,6 +169,24 @@ var json_parse = function (options) { at += 1; return ch; }, + asBigNumber = function (v) { + if (BigNumber == null) { + BigNumber = require('bignumber.js'); + } + + var bigNum = new BigNumber(v); + if (!_options.useNativeBigInt) { + return bigNum; + } + + if (!bigNum.isInteger()) { + // only case where we return BigNumber when 'useNativeBigInt' is true + // would only happen if parsing a very big decimal number + return bigNum + } + + return BigInt(bigNum.toFixed()); + }, number = function () { // Parse a number value. @@ -205,21 +223,16 @@ var json_parse = function (options) { if (!isFinite(number)) { error('Bad number'); } else { - if (BigNumber == null) BigNumber = require('bignumber.js'); //if (number > 9007199254740992 || number < -9007199254740992) // Bignumber has stricter check: everything with length > 15 digits disallowed if (string.length > 15) return _options.storeAsString ? string - : _options.useNativeBigInt - ? BigInt(string) - : new BigNumber(string); + : asBigNumber(string); else return !_options.alwaysParseAsBig ? number - : _options.useNativeBigInt - ? BigInt(number) - : new BigNumber(number); + : asBigNumber(number); } }, string = function () { diff --git a/package-lock.json b/package-lock.json index dc661f1..1e303f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -336,6 +336,15 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "fast-check": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-2.6.0.tgz", + "integrity": "sha512-Wpz0mMPGxvOtMBaEguu5Pw35uTVfJzAUqRYQksiHk6vHKBV2YNeKk9BzTuqVCYwUIl+NELyPBY2Mg96sYk2fhw==", + "dev": true, + "requires": { + "pure-rand": "^3.0.0" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -773,6 +782,12 @@ "iterate-value": "^1.0.0" } }, + "pure-rand": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-3.1.0.tgz", + "integrity": "sha512-xkCSMNjEnLG/A8iTH9M5ayXN4SCWRP+ih3rxi09Q7Fu0b9jAP6V9H59pOtcB37IsVt3eHxf1FMy9n7YrqdDdSA==", + "dev": true + }, "readdirp": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", diff --git a/package.json b/package.json index 9309f6b..00b3f2e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "devDependencies": { "chai": "4.2.0", + "fast-check": "^2.6.0", "mocha": "8.0.1" } } diff --git a/test/bigint-parse-test.js b/test/bigint-parse-test.js index e9755ff..d49a967 100644 --- a/test/bigint-parse-test.js +++ b/test/bigint-parse-test.js @@ -2,6 +2,7 @@ var mocha = require('mocha') , assert = require('chai').assert , expect = require('chai').expect , BigNumber = require('bignumber.js') + , fc = require('fast-check') ; describe("Testing native BigInt support: parse", function () { @@ -56,4 +57,14 @@ describe("Testing native BigInt support: parse", function () { expect(output).to.equal(input); done(); }); + + it("Should show JSONbig does support native Bigint parse/stringify roundtrip with any valid JSON value", function (done) { + var JSONbig = require('../index')({ + "useNativeBigInt": true + }); + fc.assert(fc.property(fc.jsonObject(), (v) => { + JSONbig.parse(JSONbig.stringify(v)) + })); + done(); + }); }); \ No newline at end of file diff --git a/test/bigint-test.js b/test/bigint-test.js index 046aa5b..1a18827 100644 --- a/test/bigint-test.js +++ b/test/bigint-test.js @@ -2,6 +2,7 @@ var mocha = require('mocha') , assert = require('chai').assert , expect = require('chai').expect , BigNumber = require('bignumber.js') + , fc = require('fast-check') ; describe("Testing bigint support", function(){ @@ -28,4 +29,12 @@ describe("Testing bigint support", function(){ expect(output).to.equal(input); done(); }); + + it("Should show JSONbig does support bigint parse/stringify roundtrip with any valid JSON value", function (done) { + var JSONbig = require('../index'); + fc.assert(fc.property(fc.jsonObject(), (v) => { + JSONbig.parse(JSONbig.stringify(v)) + })); + done(); + }); });