mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-04 13:05:49 +00:00
fix: move a tool and remove a lodash dependency (#2492)
This PR moves createValidateTests.js to xrpl/tools instead of being in the top-level tools folder, and fixes an isString import (changes it from lodash to the in-package version).
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import { isString } from 'lodash'
|
||||
|
||||
import { Amount, XChainBridge } from '../common'
|
||||
|
||||
import {
|
||||
BaseTransaction,
|
||||
isAmount,
|
||||
isXChainBridge,
|
||||
isString,
|
||||
validateBaseTransaction,
|
||||
validateRequiredField,
|
||||
} from './common'
|
||||
|
||||
187
packages/xrpl/tools/createValidateTests.js
Normal file
187
packages/xrpl/tools/createValidateTests.js
Normal file
@@ -0,0 +1,187 @@
|
||||
const fs = require('fs')
|
||||
const fixtures = require('ripple-binary-codec/test/fixtures/codec-fixtures.json')
|
||||
|
||||
const NORMAL_TYPES = ['number', 'string']
|
||||
const NUMBERS = ['0', '1']
|
||||
|
||||
function getTx(txName) {
|
||||
transactions = fixtures.transactions
|
||||
const validTxs = fixtures.transactions
|
||||
.filter((tx) => tx.json.TransactionType === txName)
|
||||
.map((tx) => tx.json)
|
||||
const validTx = validTxs[0]
|
||||
delete validTx.TxnSignature
|
||||
delete validTx.SigningPubKey
|
||||
return JSON.stringify(validTx, null, 2)
|
||||
}
|
||||
|
||||
function main() {
|
||||
const modelName = process.argv[2]
|
||||
const filename = `./packages/xrpl/src/models/transactions/${modelName}.ts`
|
||||
const [model, txName] = getModel(filename)
|
||||
return processModel(model, txName)
|
||||
}
|
||||
|
||||
// Extract just the model from the file
|
||||
function getModel(filename) {
|
||||
let model = ''
|
||||
let started = false
|
||||
let ended = false
|
||||
const data = fs.readFileSync(filename, 'utf8')
|
||||
const lines = data.split('\n')
|
||||
for (let line of lines) {
|
||||
if (ended) {
|
||||
continue
|
||||
}
|
||||
if (!started && !line.startsWith('export')) {
|
||||
continue
|
||||
}
|
||||
if (!started && line.includes('Flags')) {
|
||||
continue
|
||||
}
|
||||
if (!started) {
|
||||
started = true
|
||||
}
|
||||
model += line + '\n'
|
||||
if (line === '}') {
|
||||
ended = true
|
||||
}
|
||||
}
|
||||
const name_line = model.split('\n')[0].split(' ')
|
||||
const txName = name_line[2]
|
||||
return [model, txName]
|
||||
}
|
||||
|
||||
function getInvalidValue(paramTypes) {
|
||||
if (paramTypes.length === 1) {
|
||||
const paramType = paramTypes[0]
|
||||
if (paramType == 'number') {
|
||||
return "'number'"
|
||||
} else if (paramType == 'string') {
|
||||
return 123
|
||||
} else if (paramType == 'IssuedCurrency') {
|
||||
return JSON.stringify({ test: 'test' })
|
||||
} else if (paramType == 'Amount') {
|
||||
return JSON.stringify({ currency: 'ETH' })
|
||||
} else if (paramType == 'XChainBridge') {
|
||||
return JSON.stringify({ XChainDoor: 'test' })
|
||||
} else {
|
||||
throw Error(`${paramType} not supported yet`)
|
||||
}
|
||||
}
|
||||
|
||||
const simplifiedParamTypes = paramTypes.filter(
|
||||
(_paramType, index) => index % 2 == 0,
|
||||
)
|
||||
if (JSON.stringify(simplifiedParamTypes) === '["0","1"]') {
|
||||
return 2
|
||||
} else if (JSON.stringify(simplifiedParamTypes) === '["number","string"]') {
|
||||
return JSON.stringify({ currency: 'ETH' })
|
||||
} else {
|
||||
throw Error(`${simplifiedParamTypes} not supported yet`)
|
||||
}
|
||||
}
|
||||
|
||||
// Process the model and build the tests
|
||||
|
||||
function processModel(model, txName) {
|
||||
let output = ''
|
||||
for (let line of model.split('\n')) {
|
||||
if (line == '') {
|
||||
continue
|
||||
}
|
||||
if (line.startsWith('export')) {
|
||||
continue
|
||||
}
|
||||
if (line == '}') {
|
||||
continue
|
||||
}
|
||||
line = line.trim()
|
||||
if (line.startsWith('TransactionType')) {
|
||||
continue
|
||||
}
|
||||
if (line.startsWith('Flags')) {
|
||||
// TODO: support flag checking
|
||||
continue
|
||||
}
|
||||
if (line.startsWith('/**')) {
|
||||
continue
|
||||
}
|
||||
if (line.startsWith('*')) {
|
||||
continue
|
||||
}
|
||||
|
||||
const split = line.split(' ')
|
||||
const param = split[0].replace('?:', '').replace(':', '').trim()
|
||||
const paramTypes = split.slice(1)
|
||||
const optional = split[0].endsWith('?:')
|
||||
|
||||
if (!optional) {
|
||||
output += ` it("throws w/ missing ${param}", function () {
|
||||
delete tx.${param}
|
||||
|
||||
assert.throws(
|
||||
() => validate${txName}(tx),
|
||||
ValidationError,
|
||||
'${txName}: missing field ${param}',
|
||||
)
|
||||
assert.throws(
|
||||
() => validate(tx),
|
||||
ValidationError,
|
||||
'${txName}: missing field ${param}',
|
||||
)
|
||||
})
|
||||
|
||||
`
|
||||
}
|
||||
|
||||
const fakeValue = getInvalidValue(paramTypes)
|
||||
output += ` it('throws w/ invalid ${param}', function () {
|
||||
tx.${param} = ${fakeValue}
|
||||
|
||||
assert.throws(
|
||||
() => validate${txName}(tx),
|
||||
ValidationError,
|
||||
'${txName}: invalid field ${param}',
|
||||
)
|
||||
assert.throws(
|
||||
() => validate(tx),
|
||||
ValidationError,
|
||||
'${txName}: invalid field ${param}',
|
||||
)
|
||||
})
|
||||
|
||||
`
|
||||
}
|
||||
|
||||
output = output.substring(0, output.length - 2)
|
||||
output += '\n})\n'
|
||||
output =
|
||||
`import { assert } from 'chai'
|
||||
|
||||
import { validate, ValidationError } from '../../src'
|
||||
import { validate${txName} } from '../../src/models/transactions/${txName}'
|
||||
|
||||
/**
|
||||
* ${txName} Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('${txName}', function () {
|
||||
let tx
|
||||
|
||||
beforeEach(function () {
|
||||
tx = ${getTx(txName)} as any
|
||||
})
|
||||
|
||||
it('verifies valid ${txName}', function () {
|
||||
assert.doesNotThrow(() => validate${txName}(tx))
|
||||
assert.doesNotThrow(() => validate(tx))
|
||||
})
|
||||
|
||||
` + output
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
console.log(main())
|
||||
@@ -1,187 +0,0 @@
|
||||
const fs = require("fs");
|
||||
const fixtures = require("../packages/ripple-binary-codec/test/fixtures/codec-fixtures.json");
|
||||
|
||||
const NORMAL_TYPES = ["number", "string"];
|
||||
const NUMBERS = ["0", "1"];
|
||||
|
||||
function getTx(txName) {
|
||||
transactions = fixtures.transactions;
|
||||
const validTxs = fixtures.transactions
|
||||
.filter((tx) => tx.json.TransactionType === txName)
|
||||
.map((tx) => tx.json);
|
||||
const validTx = validTxs[0];
|
||||
delete validTx.TxnSignature;
|
||||
delete validTx.SigningPubKey;
|
||||
return JSON.stringify(validTx, null, 2);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const modelName = process.argv[2];
|
||||
const filename = `./packages/xrpl/src/models/transactions/${modelName}.ts`;
|
||||
const [model, txName] = getModel(filename);
|
||||
return processModel(model, txName);
|
||||
}
|
||||
|
||||
// Extract just the model from the file
|
||||
function getModel(filename) {
|
||||
let model = "";
|
||||
let started = false;
|
||||
let ended = false;
|
||||
const data = fs.readFileSync(filename, "utf8");
|
||||
const lines = data.split("\n");
|
||||
for (let line of lines) {
|
||||
if (ended) {
|
||||
continue;
|
||||
}
|
||||
if (!started && !line.startsWith("export")) {
|
||||
continue;
|
||||
}
|
||||
if (!started && line.includes("Flags")) {
|
||||
continue;
|
||||
}
|
||||
if (!started) {
|
||||
started = true;
|
||||
}
|
||||
model += line + "\n";
|
||||
if (line === "}") {
|
||||
ended = true;
|
||||
}
|
||||
}
|
||||
const name_line = model.split("\n")[0].split(" ");
|
||||
const txName = name_line[2];
|
||||
return [model, txName];
|
||||
}
|
||||
|
||||
function getInvalidValue(paramTypes) {
|
||||
if (paramTypes.length === 1) {
|
||||
const paramType = paramTypes[0];
|
||||
if (paramType == "number") {
|
||||
return "'number'";
|
||||
} else if (paramType == "string") {
|
||||
return 123;
|
||||
} else if (paramType == "IssuedCurrency") {
|
||||
return JSON.stringify({ test: "test" });
|
||||
} else if (paramType == "Amount") {
|
||||
return JSON.stringify({ currency: "ETH" });
|
||||
} else if (paramType == "XChainBridge") {
|
||||
return JSON.stringify({ XChainDoor: "test" });
|
||||
} else {
|
||||
throw Error(`${paramType} not supported yet`);
|
||||
}
|
||||
}
|
||||
|
||||
const simplifiedParamTypes = paramTypes.filter(
|
||||
(_paramType, index) => index % 2 == 0
|
||||
);
|
||||
if (JSON.stringify(simplifiedParamTypes) === '["0","1"]') {
|
||||
return 2;
|
||||
} else if (JSON.stringify(simplifiedParamTypes) === '["number","string"]') {
|
||||
return JSON.stringify({ currency: "ETH" });
|
||||
} else {
|
||||
throw Error(`${simplifiedParamTypes} not supported yet`);
|
||||
}
|
||||
}
|
||||
|
||||
// Process the model and build the tests
|
||||
|
||||
function processModel(model, txName) {
|
||||
let output = "";
|
||||
for (let line of model.split("\n")) {
|
||||
if (line == "") {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("export")) {
|
||||
continue;
|
||||
}
|
||||
if (line == "}") {
|
||||
continue;
|
||||
}
|
||||
line = line.trim();
|
||||
if (line.startsWith("TransactionType")) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("Flags")) {
|
||||
// TODO: support flag checking
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("/**")) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("*")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const split = line.split(" ");
|
||||
const param = split[0].replace("?:", "").replace(":", "").trim();
|
||||
const paramTypes = split.slice(1);
|
||||
const optional = split[0].endsWith("?:");
|
||||
|
||||
if (!optional) {
|
||||
output += ` it("throws w/ missing ${param}", function () {
|
||||
delete tx.${param}
|
||||
|
||||
assert.throws(
|
||||
() => validate${txName}(tx),
|
||||
ValidationError,
|
||||
'${txName}: missing field ${param}',
|
||||
)
|
||||
assert.throws(
|
||||
() => validate(tx),
|
||||
ValidationError,
|
||||
'${txName}: missing field ${param}',
|
||||
)
|
||||
})
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
const fakeValue = getInvalidValue(paramTypes);
|
||||
output += ` it('throws w/ invalid ${param}', function () {
|
||||
tx.${param} = ${fakeValue}
|
||||
|
||||
assert.throws(
|
||||
() => validate${txName}(tx),
|
||||
ValidationError,
|
||||
'${txName}: invalid field ${param}',
|
||||
)
|
||||
assert.throws(
|
||||
() => validate(tx),
|
||||
ValidationError,
|
||||
'${txName}: invalid field ${param}',
|
||||
)
|
||||
})
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
output = output.substring(0, output.length - 2);
|
||||
output += "\n})\n";
|
||||
output =
|
||||
`import { assert } from 'chai'
|
||||
|
||||
import { validate, ValidationError } from '../../src'
|
||||
import { validate${txName} } from '../../src/models/transactions/${txName}'
|
||||
|
||||
/**
|
||||
* ${txName} Transaction Verification Testing.
|
||||
*
|
||||
* Providing runtime verification testing for each specific transaction type.
|
||||
*/
|
||||
describe('${txName}', function () {
|
||||
let tx
|
||||
|
||||
beforeEach(function () {
|
||||
tx = ${getTx(txName)} as any
|
||||
})
|
||||
|
||||
it('verifies valid ${txName}', function () {
|
||||
assert.doesNotThrow(() => validate${txName}(tx))
|
||||
assert.doesNotThrow(() => validate(tx))
|
||||
})
|
||||
|
||||
` + output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
console.log(main());
|
||||
Reference in New Issue
Block a user