tests: updated testing to latest API

This commit is contained in:
Richard Moore 2022-11-27 21:59:20 -05:00
parent 2bd5df42fb
commit 433b5543e3
13 changed files with 508 additions and 65 deletions

View File

@ -4,7 +4,7 @@ import { loadTests } from "./utils.js";
import { TestCaseAbi, TestCaseAbiVerbose } from "./types.js";
import {
defaultAbiCoder, Interface,
AbiCoder, Interface,
decodeBytes32String, encodeBytes32String
} from "../index.js";
@ -32,14 +32,14 @@ describe("Tests ABI Coder", function() {
for (const test of tests) {
it(`tests ABI encoding: (${ test.name })`, function() {
const encoded = defaultAbiCoder.encode([ test.type ], [ test.value ]);
const encoded = AbiCoder.defaultAbiCoder().encode([ test.type ], [ test.value ]);
assert.equal(encoded, test.encoded, "encoded");
});
}
for (const test of tests) {
it(`tests ABI decoding: (${ test.name })`, function() {
const decoded = defaultAbiCoder.decode([ test.type ], test.encoded)[0];
const decoded = AbiCoder.defaultAbiCoder().decode([ test.type ], test.encoded)[0];
equal(decoded, test.verbose);
});
}

View File

@ -35,7 +35,7 @@ describe("computes checksum address", function() {
];
invalidAddresses.forEach(({ name, value }) => {
it(`fails on invalid address: ${ name }`, function() {
it(`correctly fails on invalid address: ${ name }`, function() {
assert.throws(function() {
getAddress(value);
}, function(error: any) {
@ -47,7 +47,7 @@ describe("computes checksum address", function() {
});
});
it("fails on invalid checksum", function() {
it("correctly fails on invalid checksum", function() {
const value = "0x8ba1f109551bD432803012645Ac136ddd64DBa72"
assert.throws(function() {
getAddress(value);
@ -59,7 +59,7 @@ describe("computes checksum address", function() {
});
});
it("fails on invalid IBAN checksum", function() {
it("correctly fails on invalid IBAN checksum", function() {
const value = "XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK37";
assert.throws(function() {
getAddress(value);
@ -108,7 +108,7 @@ describe("computes create2 address", function() {
const salt = "0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8";
const initCodeHash = "0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19afd0";
it("fails on invalid salt", function() {
it("correctly fails on invalid salt", function() {
const badSalt = "0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36dea";
assert.throws(function() {
getCreate2Address(sender, badSalt, initCodeHash);
@ -119,7 +119,7 @@ describe("computes create2 address", function() {
});
});
it("fails on invalid initCodeHash", function() {
it("correctly fails on invalid initCodeHash", function() {
const badInitCodeHash = "0x8452c9b9140222b08593a26daa782707297be9f7b3e8281d7b4974769f19af";
assert.throws(function() {
getCreate2Address(sender, salt, badInitCodeHash);

View File

@ -166,7 +166,7 @@ describe("Test Solidity Hash functions", function() {
];
for (const { types, values } of badTypes) {
it("fails on invalid type", function() {
it("correctly fails on invalid type", function() {
assert.throws(function() {
const result = solidityPacked(types, values);
console.log(result);

View File

@ -24,7 +24,7 @@ describe("Test RLP Coder", function() {
});
describe("Test bad RLP Data", function() {
it("fails encoding data with invalid values", function() {
it("correctly fails encoding data with invalid values", function() {
assert.throws(() => {
encodeRlp([ "0x1234", <string><unknown>1234 ]);
}, (error: any) => {
@ -34,7 +34,7 @@ describe("Test bad RLP Data", function() {
});
});
it("fails decoding data with trailing junk", function() {
it("correctlyfails decoding data with trailing junk", function() {
assert.throws(() => {
// Zeros_1
decodeRlp("0x0042");
@ -46,7 +46,7 @@ describe("Test bad RLP Data", function() {
});
});
it ("fails decoding short data", function() {
it ("correctlyfails decoding short data", function() {
assert.throws(() => {
decodeRlp("0x");
}, (error: any) => {
@ -58,7 +58,7 @@ describe("Test bad RLP Data", function() {
});
});
it ("fails decoding short data in child", function() {
it ("correctlyfails decoding short data in child", function() {
assert.throws(() => {
decodeRlp("0xc8880102030405060708");
}, (error: any) => {
@ -70,7 +70,7 @@ describe("Test bad RLP Data", function() {
});
});
it ("fails decoding short segment data", function() {
it ("correctlyfails decoding short segment data", function() {
assert.throws(() => {
// [["0x4243"], ["0x3145"]] = 0xc8 c3 82 4243 c3 82 3145
// XXXX

View File

@ -3,7 +3,7 @@ import { loadTests } from "./utils.js";
import type { TestCaseTransaction, TestCaseTransactionTx } from "./types.js";
import { Transaction } from "../index.js";
import { isError, Transaction } from "../index.js";
const BN_0 = BigInt(0);
@ -234,7 +234,7 @@ describe("Tests Signed Transaction Parsing", function() {
for (const test of tests) {
it(`parses signed legacy transaction: ${ test.name }`, function() {
const tx = Transaction.from(test.signedLegacy);
let tx = Transaction.from(test.signedLegacy);
const expected = addDefaults(test.transaction);
expected.maxFeePerGas = null;
@ -242,65 +242,152 @@ describe("Tests Signed Transaction Parsing", function() {
expected.accessList = null;
expected.chainId = BN_0;
for (let i = 0; i < 2; i++) {
assertTxEqual(tx, expected);
assert.equal(tx.typeName, "legacy", "typeName");
assert.equal(tx.isLegacy(), true, "isLegacy");
assert.equal(tx.isBerlin(), false, "isBerlin");
assert.equal(tx.isLondon(), false, "isLondon");
assert.ok(!!tx.signature, "signature:!null")
assert.equal(tx.signature.r, test.signatureLegacy.r, "signature.r");
assert.equal(tx.signature.s, test.signatureLegacy.s, "signature.s");
assert.equal(BigInt(tx.signature.v), BigInt(test.signatureLegacy.v), "signature.v");
tx = tx.clone();
}
});
}
for (const test of tests) {
if (!test.unsignedEip155) { continue; }
it(`parses signed EIP-155 transaction: ${ test.name }`, function() {
const tx = Transaction.from(test.signedEip155);
let tx = Transaction.from(test.signedEip155);
const expected = addDefaults(test.transaction);
expected.maxFeePerGas = null;
expected.maxPriorityFeePerGas = null;
expected.accessList = null;
for (let i = 0; i < 2; i++) {
assertTxEqual(tx, expected);
assert.equal(tx.typeName, "legacy", "typeName");
assert.equal(tx.isLegacy(), true, "isLegacy");
assert.equal(tx.isBerlin(), false, "isBerlin");
assert.equal(tx.isLondon(), false, "isLondon");
assert.ok(!!tx.signature, "signature:!null")
assert.equal(tx.signature.r, test.signatureEip155.r, "signature.r");
assert.equal(tx.signature.s, test.signatureEip155.s, "signature.s");
assert.equal(tx.signature.networkV, BigInt(test.signatureEip155.v), "signature.v");
tx = tx.clone();
}
});
}
for (const test of tests) {
it(`parses signed Berlin transaction: ${ test.name }`, function() {
const tx = Transaction.from(test.signedBerlin);
let tx = Transaction.from(test.signedBerlin);
const expected = addDefaults(test.transaction);
expected.maxFeePerGas = null;
expected.maxPriorityFeePerGas = null;
for (let i = 0; i < 2; i++) {
assertTxEqual(tx, expected);
assert.equal(tx.typeName, "eip-2930", "typeName");
assert.equal(tx.isLegacy(), false, "isLegacy");
assert.equal(tx.isBerlin(), true, "isBerlin");
assert.equal(tx.isLondon(), false, "isLondon");
assert.ok(!!tx.signature, "signature:!null")
assert.equal(tx.signature.r, test.signatureBerlin.r, "signature.r");
assert.equal(tx.signature.s, test.signatureBerlin.s, "signature.s");
assert.equal(tx.signature.yParity, parseInt(test.signatureBerlin.v), "signature.v");
tx = tx.clone();
}
});
}
for (const test of tests) {
it(`parses signed London transaction: ${ test.name }`, function() {
const tx = Transaction.from(test.signedLondon);
let tx = Transaction.from(test.signedLondon);
const expected = addDefaults(test.transaction);
expected.gasPrice = null;
for (let i = 0; i < 2; i++) {
assertTxEqual(tx, expected);
assert.equal(tx.typeName, "eip-1559", "typeName");
assert.equal(tx.isLegacy(), false, "isLegacy");
assert.equal(tx.isBerlin(), false, "isBerlin");
assert.equal(tx.isLondon(), true, "isLondon");
assert.ok(!!tx.signature, "signature:!null")
assert.equal(tx.signature.r, test.signatureLondon.r, "signature.r");
assert.equal(tx.signature.s, test.signatureLondon.s, "signature.s");
assert.equal(tx.signature.yParity, parseInt(test.signatureLondon.v), "signature.v");
// Test cloning
tx = tx.clone();
}
});
}
});
describe("Tests Transaction Parameters", function() {
const badData: Array<{ name: string, data: string, argument: string, message?: string }> = [
{
name: "accessList=0x09",
data: "0x02c9010203040580070809",
message: "invalid access list",
argument: "accessList"
},
{
name: "accessList=[0x09]",
data: "0x02ca0102030405800708c109",
message: "invalid address-slot set",
argument: "accessList"
},
{
name: "accessList=[0x09,0x10]",
data: "0x02cb0102030405800708c20910",
message: "invalid address-slot set",
argument: "accessList"
},
{
name: "accessList=[0x09,[HASH]] (bad address)",
data: "0x02ed0102030405800708e4e309e1a024412927c99a717115f5308c0ebd11136659b3cb6291abb4a8f87e9856a12538",
message: "invalid address",
argument: "accessList"
},
{
name: "accessList=[ADDR,[0x09]] (bad slot)",
data: "0x02e10102030405800708d8d794939d33ff01840e9eeeb67525ec2f7035af41a4b1c109",
message: "invalid slot",
argument: "accessList"
}
];
for (const { name, data, argument, message } of badData) {
it (`correctly fails on bad accessList: ${ name }`, function() {
assert.throws(() => {
// The access list is a single value: 0x09 instead of
// structured data
const result = Transaction.from(data);
console.log(result);
}, (error: any) => {
return (isError(error, "INVALID_ARGUMENT") &&
error.argument === argument &&
(message == null || error.message.startsWith(message)));
});
});
}
});

View File

@ -0,0 +1,180 @@
import assert from "assert";
import {
isError,
getBigInt, getNumber, toArray, toHex, toQuantity,
} from "../index.js";
describe("Tests Quantity Functions", function() {
const quantities: Array<{ name: string, value: any, expected: string }> = [
{
name: "zero number",
value: 0,
expected: "0x0"
},
{
name: "zero single hex",
value: "0x0",
expected: "0x0"
},
{
name: "zero double hex",
value: "0x00",
expected: "0x0"
},
{
name: "zero array(0)",
value: new Uint8Array([ ]),
expected: "0x0"
},
{
name: "zero array(1)",
value: new Uint8Array([ 0 ]),
expected: "0x0"
},
{
name: "single hex digit",
value: 0x5,
expected: "0x5"
},
{
name: "double hex digit",
value: 0x42,
expected: "0x42"
},
{
name: "big array, odd output",
value: new Uint8Array([ 0x0f, 254, 253, 252 ]),
expected: "0xffefdfc"
},
{
name: "big array, even output",
value: new Uint8Array([ 255, 254, 253, 252 ]),
expected: "0xfffefdfc"
},
];
for (const { name, value, expected } of quantities) {
it(`computes quantity: ${ name }`, function() {
assert.equal(toQuantity(value), expected);
});
}
});
describe("Tests Bad Math Values", function() {
const badBigInts: Array<{ name: string, value: any, error: string }> = [
{
name: "empty string",
value: "",
error: "invalid BigNumberish string"
},
{
name: "non-numeric string",
value: "foobar",
error: "invalid BigNumberish string"
},
{
name: "double negative sign",
value: "--42",
error: "invalid BigNumberish string"
},
{
name: "non-numeric thing",
value: true,
error: "invalid BigNumberish value"
},
];
for (const { name, value, error } of badBigInts) {
it(`correctly fails on bad bigint: ${ name }`, function() {
assert.throws(() => {
const result = getBigInt(value);
console.log(result);
}, (e: any) => {
return (isError(e, "INVALID_ARGUMENT") &&
e.message.startsWith(error));
});
});
}
const badNumbers: Array<{ name: string, value: any, error: string }> = [
{
name: "empty string",
value: "",
error: "invalid numeric string"
},
{
name: "non-numeric string",
value: "foobar",
error: "invalid numeric string"
},
{
name: "double negative sign",
value: "--42",
error: "invalid numeric string"
},
{
name: "non-numeric thing",
value: true,
error: "invalid numeric value"
},
{
name: "too big",
value: Number.MAX_SAFE_INTEGER + 10,
error: "overflow"
},
{
name: "too small",
value: -Number.MAX_SAFE_INTEGER - 10,
error: "overflow"
},
];
for (const { name, value, error } of badNumbers) {
it(`correctly fails on bad numeric: ${ name }`, function() {
assert.throws(() => {
const result = getNumber(value);
console.log(result);
}, (e: any) => {
return (isError(e, "INVALID_ARGUMENT") &&
e.message.startsWith(error));
});
});
}
const badHex: Array<{ name: string, value: any, error: string, width?: number }> = [
{
name: "negative value",
value: -4,
error: "cannot toHex negative value"
},
{
name: "width too short",
value: 0x123456,
width: 2,
error: "value exceeds width"
},
];
for (const { name, value, error, width } of badHex) {
it(`correctly fails on bad toHex values: ${ name }`, function() {
assert.throws(() => {
const result = toHex(value, width);
console.log(result);
}, (e: any) => {
return (isError(e, "INVALID_ARGUMENT") &&
e.message.startsWith(error));
});
});
}
it(`correctly fails on nad toArray values: negative value`, function() {
assert.throws(() => {
const result = toArray(-4);
console.log(result);
}, (e: any) => {
return (isError(e, "INVALID_ARGUMENT") &&
e.message.startsWith("cannot toArray negative value"));
});
});
});

View File

@ -2,6 +2,7 @@ import assert from "assert";
import {
decodeBase64, encodeBase64,
defineProperties, isError,
toUtf8Bytes
} from "../index.js";
@ -30,4 +31,47 @@ describe("Base64 Coding", function() {
}
});
}
})
});
describe("Test Minor Features", function() {
it("checks types in defineProperties", function() {
const any = { };
const values = {
vAny: any,
vBigint: BigInt(60),
vBoolean: true,
vNumber: 42,
vString: "some string",
};
const item: any = { };
defineProperties(item, values, {
vAny: "any",
vBigint: "bigint",
vBoolean: "boolean",
vNumber: "number",
vString: "string"
});
assert.equal(item.vAny, any, "vAny");
assert.equal(item.vBoolean, true, "vBoolenay");
assert.equal(item.vNumber, 42, "nNumber");
assert.equal(item.vString, "some string", "any");
});
it("correctly throws if defineProperty type mismatch", function() {
assert.throws(() => {
const item: any = { };
const values = { vBoolean: 42 };
defineProperties(item, values, { vBoolean: "boolean" });
console.log(values);
}, (error) => {
return (isError(error, "INVALID_ARGUMENT") &&
error.argument === "value.vBoolean" &&
error.value === 42);
});
});
});

View File

@ -55,7 +55,7 @@ describe("Tests unit conversion", function() {
});
describe("Tests bad unit conversion", function() {
it("fails to convert non-string value", function() {
it("correctly fails to convert non-string value", function() {
assert.throws(() => {
parseUnits(<any>3, "ether");
}, (error: any) => {
@ -63,7 +63,7 @@ describe("Tests bad unit conversion", function() {
});
});
it("fails to convert unknown unit", function() {
it("correctly fails to convert unknown unit", function() {
assert.throws(() => {
parseUnits("3", "foobar");
}, (error: any) => {

View File

@ -108,7 +108,7 @@ describe("Tests UTF-8 bad strings", function() {
});
}
it("fails to get UTF-8 bytes from incomplete surrogate", function() {
it("correctly fails to get UTF-8 bytes from incomplete surrogate", function() {
assert.throws(() => {
const text = String.fromCharCode(0xd800);;
const result = toUtf8Bytes(text);
@ -118,7 +118,7 @@ describe("Tests UTF-8 bad strings", function() {
});
});
it("fails to get UTF-8 bytes from invalid surrogate pair", function() {
it("correctly fails to get UTF-8 bytes from invalid surrogate pair", function() {
assert.throws(() => {
const text = String.fromCharCode(0xd800, 0xdbff);;
const result = toUtf8Bytes(text);

View File

@ -5,11 +5,15 @@ import { loadTests } from "./utils.js";
import type { TestCaseWallet } from "./types.js";
import {
decryptCrowdsaleJson,
decryptKeystoreJson, decryptKeystoreJsonSync,
Wallet
isError,
decryptCrowdsaleJson, decryptKeystoreJson, decryptKeystoreJsonSync,
encryptKeystoreJson, encryptKeystoreJsonSync,
isCrowdsaleJson,
HDNodeWallet, Wallet
} from "../index.js";
describe("Tests JSON Wallet Formats", function() {
const tests = loadTests<TestCaseWallet>("wallets");
tests.forEach((test) => {
@ -62,4 +66,121 @@ describe("Tests JSON Wallet Formats", function() {
assert.equal(wallet.address, test.address, "address");
});
});
it("tests encrypting wallet with mnemonic", function() {
this.timeout(20000);
const wallet = HDNodeWallet.createRandom();
assert.ok(wallet.mnemonic, "mnemonic");
const phrase = wallet.mnemonic.phrase;
const json = wallet.encryptSync("foobar");
const wallet2 = Wallet.fromEncryptedJsonSync(json, "foobar");
assert.ok(wallet2 instanceof HDNodeWallet && wallet2.mnemonic);
assert.equal(wallet2.mnemonic.phrase, phrase, "phrase");
assert.equal(wallet2.address, wallet.address, "address");
});
});
describe("Tests Extra JSON Wallet Functions", function() {
const badCrowdsales: Array<{ name: string, value: any }> = [
{
name: "undefined",
value: undefined
},
{
name: "junk string",
value: "junk!"
},
{
name: "non-string",
value: 42
},
{
name: "JSON without encseed",
value: JSON.stringify({ foo: "bar" })
},
];
for (const { name, value } of badCrowdsales) {
it(`tests the invalid isCrowdsale wallet: ${ name }`, function() {
assert.equal(isCrowdsaleJson(value), false);
});
}
const badKeystoreOptions: Array<{ name: string, options: any, error: string }> = [
{
name: "invalid salt type",
options: { salt: 42 },
error: "invalid BytesLike value"
},
{
name: "invalid uuid type",
options: { uuid: 42 },
error: "invalid BytesLike value"
},
{
name: "invalid uuid length",
options: { uuid: "0x1234" },
error: "invalid options.uuid"
},
{
name: "invalid iv type",
options: { iv: 42 },
error: "invalid BytesLike value"
},
{
name: "invalid iv length",
options: { iv: "0x1234" },
error: "invalid options.iv"
},
{
name: "invalid scrypt N (non-one-hot-encoded)",
options: { scrypt: { N: 1023 } },
error: "invalid scrypt N parameter"
},
{
name: "invalid scrypt N (non-integer)",
options: { scrypt: { N: 1.5 } },
error: "invalid scrypt N parameter"
},
{
name: "invalid scrypt r",
options: { scrypt: { r: 1.5 } },
error: "invalid scrypt r parameter"
},
{
name: "invalid scrypt p",
options: { scrypt: { p: 1.5 } },
error: "invalid scrypt p parameter"
},
];
const wallet = Wallet.createRandom();
const account = { address: wallet.address, privateKey: wallet.privateKey };
const password = "foobar";
for (const { name, options, error } of badKeystoreOptions) {
it(`tests bad keystore options: ${ name }`, function() {
assert.throws(() => {
const result = encryptKeystoreJsonSync(account, password, options);
console.log(result);
}, (e: any) => {
return (isError(e, "INVALID_ARGUMENT") &&
e.message.startsWith(error));
});
});
}
// Mainly to round out weird edge cases in coverage
it("tests encryption with options (sync)", function() {
assert.ok(encryptKeystoreJsonSync(account, password));
});
// Mainly to round out weird edge cases in coverage
it("tests encryption with options (async)", async function() {
assert.ok(await encryptKeystoreJson(account, password));
});
});

View File

@ -81,7 +81,7 @@ describe("Tests Bad Mnemonics Fail", function() {
for (const _phrase of badLengths) {
const phrase = _phrase.join(" ");
it(`fails on invalid mnemonic length: ${ _phrase.length }`, function() {
it(`correctly fails on invalid mnemonic length: ${ _phrase.length }`, function() {
assert.ok(!Mnemonic.isValidMnemonic(phrase));
assert.throws(function() {
Mnemonic.fromPhrase(phrase);
@ -94,7 +94,7 @@ describe("Tests Bad Mnemonics Fail", function() {
});
}
it("fails on invalid mnemonic word", function() {
it("correctly fails on invalid mnemonic word", function() {
const phrase = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon wagmi";
assert.ok(!Mnemonic.isValidMnemonic(phrase));
assert.throws(function() {
@ -107,7 +107,7 @@ describe("Tests Bad Mnemonics Fail", function() {
});
});
it("fails on invalid mnemonic checksum", function() {
it("correctly fails on invalid mnemonic checksum", function() {
const phrase = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon";
assert.ok(!Mnemonic.isValidMnemonic(phrase));
assert.throws(function() {
@ -129,7 +129,7 @@ describe("Tests Bad Mnemonics Fail", function() {
for (const _entropy of badEntropyLengths) {
const entropy = "0x" + _entropy.join("");
it(`fails on invalid entropy length: ${ _entropy.length }`, function() {
it(`correctly fails on invalid entropy length: ${ _entropy.length }`, function() {
assert.throws(function() {
Mnemonic.fromEntropy(entropy);
}, function(error: any) {

View File

@ -7,7 +7,9 @@ import type {
} from "./types.js";
import { Wallet } from "../index.js";
import { hexlify, randomBytes, Wallet } from "../index.js";
import type { HDNodeWallet } from "../index.js";
describe("Test Private Key Wallet", function() {
@ -85,17 +87,25 @@ describe("Test Typed-Data Signing (EIP-712)", function() {
describe("Test Wallet Encryption", function() {
const password = "foobar";
it("encrypts a wallet: sync", function() {
const wallet = Wallet.createRandom();
// Loop:
// 1 : random wallet (uses HDNodeWallet under the hood)
// 2 : Wallet using private key (uses Wallet explicitly)
for (let i = 0; i < 2; i++) {
let wallet: Wallet | HDNodeWallet = Wallet.createRandom();
it("encrypts a random wallet: sync", function() {
const json = wallet.encryptSync(password);
const decrypted = Wallet.fromEncryptedJsonSync(json, password);
assert.equal(decrypted.address, wallet.address, "address");
});
it("encrypts a wallet: async", async function() {
const wallet = Wallet.createRandom();
it("encrypts a random wallet: async", async function() {
const json = await wallet.encrypt(password);
const decrypted = await Wallet.fromEncryptedJson(json, password);
assert.equal(decrypted.address, wallet.address, "address");
});
wallet = new Wallet(hexlify(randomBytes(32)));
}
});

View File

@ -1,12 +1,13 @@
import assert from 'assert';
import { wordlists } from "../index.js";
import { wordlists } from "../wordlists/wordlists.js";
import { loadTests } from "./utils.js";
import type { TestCaseWordlist } from "./types.js";
describe('Check Wordlists', function() {
const tests = loadTests<TestCaseWordlist>("wordlists");