ethers.js/packages/testcases/generation/lib/abi-test.js

133 lines
4.8 KiB
JavaScript
Raw Permalink Normal View History

2020-10-18 23:19:16 -04:00
"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;