mirror of
				https://github.com/Xahau/xahau.js.git
				synced 2025-11-04 04:55:48 +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