"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const test_1 = require("./test"); class AbstractAbiTest extends test_1.AbstractTest { constructor(name) { super(name); this._nextNames = {}; } nextName(prefix) { if (prefix == null) { prefix = "p"; } if (!this._nextNames[prefix]) { this._nextNames[prefix] = 1; } return prefix + (this._nextNames[prefix]++); } randomType(dynamicOrType) { if (dynamicOrType == null) { dynamicOrType = true; } let type = null; let dynamic = true; if (typeof (dynamicOrType) === "boolean") { dynamic = dynamicOrType; type = this.randomInteger(0, dynamic ? 8 : 6); } else { type = dynamicOrType; } const name = this.nextName(); switch (type) { // Static // address case 0: case "address": return { name, type: "address", create: () => { return this.randomAddress(); } }; // bool case 1: case "bool": return { name, type: "bool", create: () => { return this.randomChoice([false, true]); } }; // intXX and uintXX case 2: case "number": { const signed = this.randomChoice([false, true]); const width = this.randomInteger(1, 33); return { name, type: `${signed ? "" : "u"}int${width * 8}`, create: () => { const bytes = this.randomBytes(width); let value = BigInt("0x" + bytes.toString("hex")); if (signed && (bytes[0] & 0x80)) { bytes[0] &= ~0x80; value = -BigInt("0x" + bytes.toString("hex")); } return value.toString(); } }; } // bytesXX case 3: case "bytesX": { const width = this.randomInteger(1, 33); return { name, type: `bytes${width}`, create: () => { return this.randomHexString(width); } }; } // Static or dynamic nested types // Array case 4: case "array": { const baseType = this.randomType(dynamic); let length = this.randomInteger(0, 4); if (length == 0) { length = null; } const lengthString = ((length == null) ? "" : String(length)); let struct = undefined; let components = undefined; if (baseType.struct) { struct = `${baseType.struct}[${lengthString}]`; components = baseType.components; } return { name, components, struct, type: `${baseType.type}[${lengthString}]`, create: () => { let l = length; if (l == null) { l = this.randomInteger(0, 4); } const result = []; for (let i = 0; i < l; i++) { result.push(baseType.create()); } return result; } }; } // Tuple case 5: case "tuple": { const components = []; const length = this.randomInteger(1, 5); for (let i = 0; i < length; i++) { components.push(this.randomType(dynamic)); } const struct = this.nextName("Struct"); const type = `tuple(${components.map(c => c.type).join(",")})`; return { name, struct, type, components, create: () => { const result = {}; components.forEach((type) => { result[type.name] = type.create(); }); return result; } }; } // Dynamic // string case 6: case "string": return { name, type: "string", create: () => { return this.randomString(0, 64); } }; // bytes case 7: case "bytes": return { name, type: "bytes", create: () => { return this.randomHexString(0, 64); } }; } throw new Error("should not be reached"); } } exports.AbstractAbiTest = AbstractAbiTest;