Lints test/utils (#1575)

* rename model tests

* rename util tests

* turn off `any` complaints in linter

* other linter changes

* fix xrp <-> drops methods

* lint generateAddress

* fix rest of tests
This commit is contained in:
Mayukha Vadari
2021-09-01 14:15:49 -04:00
parent 89e319fe0a
commit b051b4c59b
27 changed files with 129 additions and 123 deletions

View File

@@ -2,98 +2,105 @@ module.exports = {
root: true,
// Make ESLint compatible with TypeScript
parser: '@typescript-eslint/parser',
parser: "@typescript-eslint/parser",
parserOptions: {
// Enable linting rules with type information from our tsconfig
tsconfigRootDir: __dirname,
project: ['./tsconfig.eslint.json'],
project: ["./tsconfig.eslint.json"],
// Allow the use of imports / ES modules
sourceType: 'module',
sourceType: "module",
ecmaFeatures: {
// Enable global strict mode
impliedStrict: true
}
impliedStrict: true,
},
},
// Specify global variables that are predefined
env: {
node: true, // Enable node global variables & Node.js scoping
es2020: true // Add all ECMAScript 2020 globals and automatically set the ecmaVersion parser option to ES2020
es2020: true, // Add all ECMAScript 2020 globals and automatically set the ecmaVersion parser option to ES2020
},
plugins: [],
extends: ['@xrplf/eslint-config/base', 'plugin:mocha/recommended'],
extends: ["@xrplf/eslint-config/base", "plugin:mocha/recommended"],
rules: {
// Certain rippled APIs require snake_case naming
'@typescript-eslint/naming-convention': [
'error',
"@typescript-eslint/naming-convention": [
"error",
{
selector: 'interface',
format: ['PascalCase']
selector: "interface",
format: ["PascalCase"],
},
{
selector: 'interface',
format: ['snake_case']
}
selector: "interface",
format: ["snake_case"],
},
],
// Ignore type imports when counting dependencies.
'import/max-dependencies': [
'error',
"import/max-dependencies": [
"error",
{
max: 5,
ignoreTypeImports: true
}
ignoreTypeImports: true,
},
],
// Removes comments and blank lines from the max-line rules
'max-lines-per-function': [
'warn',
"max-lines-per-function": [
"warn",
{
max: 50,
skipBlankLines: true,
skipComments: true
}
skipComments: true,
},
],
'max-lines': [
'warn',
"max-lines": [
"warn",
{
max: 250,
skipBlankLines: true,
skipComments: true
}
]
skipComments: true,
},
],
},
overrides: [
{
files: ['test/**/*.ts'],
files: ["test/**/*.ts"],
rules: {
// Removed the max for test files and test helper files, since tests usually need to import more things
'import/max-dependencies': 'off',
"import/max-dependencies": "off",
// describe blocks count as a function in Mocha tests, and can be insanely long
'max-lines-per-function': 'off',
"max-lines-per-function": "off",
// Tests can be very long turns off max-line count
'max-lines': 'off',
"max-lines": "off",
// We have lots of statements in tests
'max-statements': 'off',
"max-statements": "off",
// We have lots of magic numbers in tests
'no-magic-number': 'off'
}
"no-magic-number": "off",
"@typescript-eslint/no-magic-numbers": "off",
// We need to test things without type guards sometimes
"@typescript-eslint/no-unsafe-assignment": "off",
// We need to mess with internal things to generate certain testing situations
"@typescript-eslint/no-unsafe-member-access": "off",
},
},
{
files: ['.eslintrc.js', 'jest.config.js'],
files: [".eslintrc.js", "jest.config.js"],
rules: {
// Removed no-commonjs requirement as eslint must be in common js format
'import/no-commonjs': 'off',
"import/no-commonjs": "off",
// Removed this as eslint prevents us from doing this differently
'import/unambiguous': 'off'
}
}
]
}
"import/unambiguous": "off",
},
},
],
};

View File

@@ -9,7 +9,7 @@ import { verifyAccountDelete } from "../../src/models/transactions/accountDelete
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("AccountDelete Transaction Verification", function () {
describe("AccountDelete", function () {
it(`verifies valid AccountDelete`, function () {
const validAccountDelete = {
TransactionType: "AccountDelete",

View File

@@ -9,7 +9,7 @@ import { verifyAccountSet } from "../../src/models/transactions/accountSet";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("AccountSet Transaction Verification", function () {
describe("AccountSet", function () {
let account;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyBaseTransaction } from "../../src/models/transactions/common";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("Transaction Verification", function () {
describe("BaseTransaction", function () {
it(`Verifies all optional BaseTransaction`, function () {
const txJson = {
Account: "r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe",

View File

@@ -9,7 +9,7 @@ import { verifyCheckCancel } from "../../src/models/transactions/checkCancel";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("CheckCancel Transaction Verification", function () {
describe("CheckCancel", function () {
it(`verifies valid CheckCancel`, function () {
const validCheckCancel = {
Account: "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",

View File

@@ -9,7 +9,7 @@ import { verifyCheckCash } from "../../src/models/transactions/checkCash";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("CheckCash Transaction Verification", function () {
describe("CheckCash", function () {
it(`verifies valid CheckCash`, function () {
const validCheckCash = {
Account: "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",

View File

@@ -9,7 +9,7 @@ import { verifyCheckCreate } from "../../src/models/transactions/checkCreate";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("CheckCreate Transaction Verification", function () {
describe("CheckCreate", function () {
it(`verifies valid CheckCreate`, function () {
const validCheck = {
TransactionType: "CheckCreate",

View File

@@ -9,7 +9,7 @@ import { verifyDepositPreauth } from "../../src/models/transactions/depositPreau
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("DepositPreauth Transaction Verification", function () {
describe("DepositPreauth", function () {
let depositPreauth;
beforeEach(function () {

View File

@@ -8,7 +8,7 @@ import { verifyEscrowCancel } from "../../src/models/transactions/escrowCancel";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("Transaction Verification", function () {
describe("EscrowCancel", function () {
let cancel;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyEscrowCreate } from "../../src/models/transactions/escrowCreate";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("EscrowCreate Transaction Verification", function () {
describe("EscrowCreate", function () {
let escrow;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyEscrowFinish } from "../../src/models/transactions/escrowFinish";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("EscrowFinish Transaction Verification", function () {
describe("EscrowFinish", function () {
let escrow;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyOfferCancel } from "../../src/models/transactions/offerCancel";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("OfferCancel Transaction Verification", function () {
describe("OfferCancel", function () {
let offer;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyOfferCreate } from "../../src/models/transactions/offerCreate";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("OfferCreate Transaction Verification", function () {
describe("OfferCreate", function () {
it(`verifies valid OfferCreate`, function () {
const offer = {
Account: "r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W",

View File

@@ -12,7 +12,7 @@ import {
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("Payment Transaction Verification", function () {
describe("Payment", function () {
let paymentTransaction;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyPaymentChannelClaim } from "../../src/models/transactions/payment
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("PaymentChannelClaim Transaction Verification", function () {
describe("PaymentChannelClaim", function () {
let channel;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyPaymentChannelCreate } from "../../src/models/transactions/paymen
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("PaymentChannelCreate Transaction Verification", function () {
describe("PaymentChannelCreate", function () {
let channel;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyPaymentChannelFund } from "../../src/models/transactions/paymentC
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("PaymentChannelFund Transaction Verification", function () {
describe("PaymentChannelFund", function () {
let channel;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifySetRegularKey } from "../../src/models/transactions/setRegularKey
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("SetRegularKey Transaction Verification", function () {
describe("SetRegularKey", function () {
let account;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifySignerListSet } from "../../src/models/transactions/signerListSet
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("SignerListSet Transaction Verification", function () {
describe("SignerListSet", function () {
let SignerListSetTx;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyTicketCreate } from "../../src/models/transactions/ticketCreate";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("TicketCreate Transaction Verification", function () {
describe("TicketCreate", function () {
let ticketCreate;
beforeEach(function () {

View File

@@ -9,7 +9,7 @@ import { verifyTrustSet } from "../../src/models/transactions/trustSet";
*
* Providing runtime verification testing for each specific transaction type.
*/
describe("TrustSet Transaction Verification", function () {
describe("TrustSet", function () {
let trustSet;
beforeEach(function () {

View File

@@ -8,17 +8,13 @@ import { assertResultMatch } from "../testUtils";
const { computeLedgerHash: REQUEST_FIXTURES } = requests;
function getNewLedger() {
return JSON.parse(JSON.stringify(responses.getLedger.full));
}
describe("Compute Ledger Hash", function () {
describe("computeLedgerHash", function () {
it("given corrupt data - should fail", function () {
const ledger = getNewLedger();
const ledger = JSON.parse(JSON.stringify(responses.getLedger.full));
ledger.transactions[0].rawTransaction =
'{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Amount":"12000000000","Destination":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Fee":"10","Flags":0,"Sequence":62,"SigningPubKey":"034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E","TransactionType":"Payment","TxnSignature":"3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639","hash":"3B1A4E1C9BB6A7208EB146BCDB86ECEA6068ED01466D933528CA2B4C64F753EF","meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"4C6ACBD635B0F07101F7FA25871B0925F8836155462152172755845CE691C49E","NewFields":{"Account":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Balance":"10000000000","Sequence":1}}},{"ModifiedNode":{"FinalFields":{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Balance":"981481999380","Flags":0,"OwnerCount":0,"Sequence":63},"LedgerEntryType":"AccountRoot","LedgerIndex":"B33FDD5CF3445E1A7F2BE9B06336BEBD73A5E3EE885D3EF93F7E3E2992E46F1A","PreviousFields":{"Balance":"991481999390","Sequence":62},"PreviousTxnID":"2485FDC606352F1B0785DA5DE96FB9DBAF43EB60ECBB01B7F6FA970F512CDA5F","PreviousTxnLgrSeq":31317}}],"TransactionIndex":0,"TransactionResult":"tesSUCCESS"},"ledger_index":38129}';
ledger.parentCloseTime = ledger.closeTime;
let hash;
let hash: string;
try {
hash = computeLedgerHeaderHash(ledger, { computeTreeHashes: true });
} catch (error) {
@@ -42,18 +38,15 @@ describe("Compute Ledger Hash", function () {
});
it("given ledger without raw transactions - should throw", function () {
const ledger = getNewLedger();
const ledger = JSON.parse(JSON.stringify(responses.getLedger.full));
delete ledger.transactions[0].rawTransaction;
ledger.parentCloseTime = ledger.closeTime;
let hash;
let hash: string;
try {
hash = computeLedgerHeaderHash(ledger, { computeTreeHashes: true });
} catch (error) {
assert(error instanceof ValidationError);
assert.strictEqual(
error.message,
"ledger" + " is missing raw transactions"
);
assert.strictEqual(error.message, "ledger is missing raw transactions");
return;
}
assert(
@@ -63,22 +56,22 @@ describe("Compute Ledger Hash", function () {
});
it("given ledger without state or transactions - only compute ledger hash", function () {
const ledger = getNewLedger();
const ledger = JSON.parse(JSON.stringify(responses.getLedger.full));
assert.strictEqual(
ledger.transactions[0].rawTransaction,
'{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Amount":"10000000000","Destination":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Fee":"10","Flags":0,"Sequence":62,"SigningPubKey":"034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E","TransactionType":"Payment","TxnSignature":"3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639","hash":"3B1A4E1C9BB6A7208EB146BCDB86ECEA6068ED01466D933528CA2B4C64F753EF","meta":{"AffectedNodes":[{"CreatedNode":{"LedgerEntryType":"AccountRoot","LedgerIndex":"4C6ACBD635B0F07101F7FA25871B0925F8836155462152172755845CE691C49E","NewFields":{"Account":"rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj","Balance":"10000000000","Sequence":1}}},{"ModifiedNode":{"FinalFields":{"Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","Balance":"981481999380","Flags":0,"OwnerCount":0,"Sequence":63},"LedgerEntryType":"AccountRoot","LedgerIndex":"B33FDD5CF3445E1A7F2BE9B06336BEBD73A5E3EE885D3EF93F7E3E2992E46F1A","PreviousFields":{"Balance":"991481999390","Sequence":62},"PreviousTxnID":"2485FDC606352F1B0785DA5DE96FB9DBAF43EB60ECBB01B7F6FA970F512CDA5F","PreviousTxnLgrSeq":31317}}],"TransactionIndex":0,"TransactionResult":"tesSUCCESS"},"ledger_index":38129}'
);
ledger.parentCloseTime = ledger.closeTime;
const computeLedgerHash = computeLedgerHeaderHash;
function testCompute(ledger, expectedError) {
let hash = computeLedgerHash(ledger);
function testCompute(ledgerToCompute, expectedError): void {
let hash = computeLedgerHash(ledgerToCompute);
assert.strictEqual(
hash,
"E6DB7365949BF9814D76BCC730B01818EB9136A89DB224F3F9F5AAE4569D758E"
);
// fail if required to compute tree hashes
try {
hash = computeLedgerHash(ledger, { computeTreeHashes: true });
hash = computeLedgerHash(ledgerToCompute, { computeTreeHashes: true });
} catch (error) {
assert(error instanceof ValidationError);
assert.strictEqual(error.message, expectedError);
@@ -100,7 +93,7 @@ describe("Compute Ledger Hash", function () {
});
it("wrong hash", function () {
const ledger = getNewLedger();
const ledger = JSON.parse(JSON.stringify(responses.getLedger.full));
assertResultMatch(ledger, responses.getLedger.full, "getLedger");
const newLedger = {
...ledger,
@@ -110,7 +103,7 @@ describe("Compute Ledger Hash", function () {
};
assert.throws(() => {
computeLedgerHeaderHash(newLedger);
}, /does not match computed hash of state/);
}, /does not match computed hash of state/u);
});
it("computeLedgerHash", function () {

View File

@@ -3,7 +3,7 @@ import { assert } from "chai";
import { dropsToXrp } from "../../src/utils";
describe("Drops To XRP", function () {
describe("dropsToXrp", function () {
it("works with a typical amount", function () {
const xrp = dropsToXrp("2000000");
assert.strictEqual(xrp, "2", "2 million drops equals 2 XRP");
@@ -87,38 +87,38 @@ describe("Drops To XRP", function () {
it("throws with an amount with too many decimal places", function () {
assert.throws(() => {
dropsToXrp("1.2");
}, /has too many decimal places/);
}, /has too many decimal places/u);
assert.throws(() => {
dropsToXrp("0.10");
}, /has too many decimal places/);
}, /has too many decimal places/u);
});
it("throws with an invalid value", function () {
assert.throws(() => {
dropsToXrp("FOO");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
dropsToXrp("1e-7");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
dropsToXrp("2,0");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
dropsToXrp(".");
}, /dropsToXrp: invalid value '\.', should be a BigNumber or string-encoded number\./);
}, /dropsToXrp: invalid value '\.', should be a BigNumber or string-encoded number\./u);
});
it("throws with an amount more than one decimal point", function () {
assert.throws(() => {
dropsToXrp("1.0.0");
}, /dropsToXrp: invalid value '1\.0\.0'/);
}, /dropsToXrp: invalid value '1\.0\.0'/u);
assert.throws(() => {
dropsToXrp("...");
}, /dropsToXrp: invalid value '\.\.\.'/);
}, /dropsToXrp: invalid value '\.\.\.'/u);
});
});

View File

@@ -8,16 +8,12 @@ import {
} from "../../src/utils/generateAddress";
import responses from "../fixtures/responses";
describe("Generate Address", function () {
describe("generateAddress", function () {
it("generateAddress", function () {
// GIVEN entropy of all zeros
function random() {
return new Array(16).fill(0);
}
assert.deepEqual(
// GIVEN entropy of all zeros
// WHEN generating an address
generateXAddress({ entropy: random() }),
generateXAddress({ entropy: new Array(16).fill(0) }),
// THEN we get the expected return value
responses.generateXAddress
@@ -27,12 +23,8 @@ describe("Generate Address", function () {
it("generateAddress invalid entropy", function () {
assert.throws(() => {
// GIVEN entropy of 1 byte
function random() {
return new Array(1).fill(0);
}
// WHEN generating an address
generateXAddress({ entropy: random() });
generateXAddress({ entropy: new Array(1).fill(0) });
// THEN an UnexpectedError is thrown
// because 16 bytes of entropy are required
@@ -194,7 +186,8 @@ describe("Generate Address", function () {
// THEN we get the expected return value
const response = {
...responses.generateAddress, // generateAddress return value always includes xAddress to encourage X-address adoption
// generateAddress return value always includes xAddress to encourage X-address adoption
...responses.generateAddress,
xAddress: "TVG3TcCD58BD6MZqsNuTihdrhZwR8SzvYS8U87zvHsAcNw4",
};
assert.deepEqual(account, response);

View File

@@ -1,5 +1,6 @@
import assert from "assert";
import fs from "fs";
import { join } from "path";
import {
computeStateTreeHash,
@@ -15,12 +16,17 @@ import {
/**
* Expects a corresponding ledger dump in $repo/test/fixtures/rippled folder.
*
* @param ledgerIndex
* @param ledgerIndex - The ledger index of the desired dump.
*/
function createLedgerTest(ledgerIndex: number) {
describe(String(ledgerIndex), function () {
const path = `${__dirname}/../fixtures/rippled/ledgerFull${ledgerIndex}.json`;
function createLedgerTest(ledgerIndex: number): void {
const ledgerIndexString = String(ledgerIndex);
const path = join(
__dirname,
"..",
`fixtures/rippled/ledgerFull${ledgerIndex}.json`
);
// eslint-disable-next-line node/no-sync -- must be sync version when not in async method
const ledgerRaw = fs.readFileSync(path, { encoding: "utf8" });
const ledgerJSON = JSON.parse(ledgerRaw);
@@ -28,7 +34,9 @@ function createLedgerTest(ledgerIndex: number) {
Array.isArray(ledgerJSON.accountState) &&
ledgerJSON.accountState.length > 0;
describe(`ledger hashes ${ledgerIndexString}`, function () {
if (hasAccounts) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- known to be a string
it(`has account_hash of ${ledgerJSON.account_hash}`, function () {
assert.equal(
ledgerJSON.account_hash,
@@ -36,6 +44,7 @@ function createLedgerTest(ledgerIndex: number) {
);
});
}
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- known to be a string
it(`has transaction_hash of ${ledgerJSON.transaction_hash}`, function () {
assert.equal(
ledgerJSON.transaction_hash,
@@ -45,12 +54,15 @@ function createLedgerTest(ledgerIndex: number) {
});
}
describe("Ledger", function () {
describe("Hashes", function () {
// This is the first recorded ledger with a non empty transaction set
// eslint-disable-next-line mocha/no-setup-in-describe -- runs tests
createLedgerTest(38129);
// Because, why not.
// eslint-disable-next-line mocha/no-setup-in-describe -- runs tests
createLedgerTest(40000);
// 1311 AffectedNodes, no accounts
// eslint-disable-next-line mocha/no-setup-in-describe -- runs tests
createLedgerTest(7501326);
describe("calcAccountRootEntryHash", function () {

View File

@@ -3,7 +3,7 @@ import requests from "../fixtures/requests";
import responses from "../fixtures/responses";
import { assertResultMatch } from "../testUtils";
describe("Verify Payment Channel Claim", function () {
describe("verifyPaymentChannelClaim", function () {
it("basic verification works", function () {
const publicKey =
"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8";

View File

@@ -3,7 +3,7 @@ import { assert } from "chai";
import { xrpToDrops } from "../../src/utils";
describe("XRP To Drops", function () {
describe("xrpToDrops", function () {
it("works with a typical amount", function () {
const drops = xrpToDrops("2");
assert.strictEqual(drops, "2000000", "2 XRP equals 2 million drops");
@@ -23,7 +23,8 @@ describe("XRP To Drops", function () {
it("works with zero", function () {
let drops = xrpToDrops("0");
assert.strictEqual(drops, "0", "0 XRP equals 0 drops");
drops = xrpToDrops("-0"); // negative zero is equivalent to zero
// negative zero is equivalent to zero
drops = xrpToDrops("-0");
assert.strictEqual(drops, "0", "-0 XRP equals 0 drops");
drops = xrpToDrops("0.000000");
assert.strictEqual(drops, "0", "0.000000 XRP equals 0 drops");
@@ -77,33 +78,33 @@ describe("XRP To Drops", function () {
it("throws with an amount with too many decimal places", function () {
assert.throws(() => {
xrpToDrops("1.1234567");
}, /has too many decimal places/);
}, /has too many decimal places/u);
assert.throws(() => {
xrpToDrops("0.0000001");
}, /has too many decimal places/);
}, /has too many decimal places/u);
});
it("throws with an invalid value", function () {
assert.throws(() => {
xrpToDrops("FOO");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
xrpToDrops("1e-7");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
xrpToDrops("2,0");
}, /invalid value/);
}, /invalid value/u);
assert.throws(() => {
xrpToDrops(".");
}, /xrpToDrops: invalid value '\.', should be a BigNumber or string-encoded number\./);
}, /xrpToDrops: invalid value '\.', should be a BigNumber or string-encoded number\./u);
});
it("throws with an amount more than one decimal point", function () {
assert.throws(() => {
xrpToDrops("1.0.0");
}, /xrpToDrops: invalid value '1\.0\.0'/);
}, /xrpToDrops: invalid value '1\.0\.0'/u);
assert.throws(() => {
xrpToDrops("...");
}, /xrpToDrops: invalid value '\.\.\.'/);
}, /xrpToDrops: invalid value '\.\.\.'/u);
});
});