Skip to content

Commit 1cfe496

Browse files
committed
Added tests to help fill out coverage tests.
1 parent 79b1da1 commit 1cfe496

File tree

5 files changed

+436
-16
lines changed

5 files changed

+436
-16
lines changed

packages/tests/src.ts/test-hdnode.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,94 @@ describe('Test HD Mnemonic Phrases', function testMnemonic() {
141141
});
142142
});
143143

144+
describe("HD Extended Keys", function() {
145+
const root = ethers.utils.HDNode.fromSeed("0xdeadbeefdeadbeefdeadbeefdeadbeef");
146+
const root42 = root.derivePath("42");
147+
148+
it("exports and imports xpriv extended keys", function() {
149+
const xpriv = root.extendedKey;
150+
const node = ethers.utils.HDNode.fromExtendedKey(xpriv);
151+
152+
assert.equal(root.address, node.address, "address matches");
153+
154+
const node42 = node.derivePath("42");
155+
assert.equal(root42.address, node42.address, "address matches");
156+
});
157+
158+
it("exports and imports xpub extended keys", function() {
159+
const xpub = root.neuter().extendedKey;
160+
const node = ethers.utils.HDNode.fromExtendedKey(xpub);
161+
162+
assert.equal(root.address, node.address, "address matches");
163+
164+
const node42 = node.derivePath("42");
165+
assert.equal(root42.address, node42.address, "address matches");
166+
});
167+
});
168+
169+
describe("HD error cases", function() {
170+
const testInvalid = [
171+
"",
172+
"m/45/m",
173+
"m/44/foobar"
174+
];
175+
176+
const root = ethers.utils.HDNode.fromSeed("0xdeadbeefdeadbeefdeadbeefdeadbeef");
177+
178+
testInvalid.forEach((path) => {
179+
it(`fails on path "${ path }"`, function() {
180+
assert.throws(() => {
181+
root.derivePath(path);
182+
}, (error: any) => {
183+
return true;
184+
});
185+
});
186+
});
187+
188+
it("fails to derive child of hardened key", function() {
189+
// Deriving non-hardened should work...
190+
const node = root.neuter().derivePath("44");
191+
192+
assert.throws(() => {
193+
// Deriving hardened should fail...
194+
node.derivePath("44'");
195+
}, (error: any) => {
196+
return true;
197+
});
198+
});
199+
200+
// The zero-mnemonic, with and without correct checksum
201+
const zeroMnemonicCS = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
202+
const zeroMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon";
203+
204+
it("fails on invalid mnemonic length", function() {
205+
const shortMnemonic = "abandon abandon abandon abandon";
206+
207+
// Test the validate functions
208+
assert.ok(ethers.utils.isValidMnemonic(zeroMnemonicCS));
209+
assert.ok(!ethers.utils.isValidMnemonic(zeroMnemonic));
210+
assert.ok(!ethers.utils.isValidMnemonic(shortMnemonic));
211+
212+
assert.throws(() => {
213+
ethers.utils.mnemonicToEntropy(shortMnemonic);
214+
}, (error: any) => {
215+
return true;
216+
});
217+
});
218+
219+
it("fails on invalid checksum", function() {
220+
assert.throws(() => {
221+
ethers.utils.mnemonicToEntropy(zeroMnemonic);
222+
}, (error: any) => {
223+
return true;
224+
});
225+
});
226+
227+
it("fails on unknown locale", function() {
228+
assert.throws(() => {
229+
ethers.utils.HDNode.fromMnemonic(zeroMnemonicCS, "foobar", "xx");
230+
}, (error: any) => {
231+
return true;
232+
});
233+
});
234+
});

packages/tests/src.ts/test-providers.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,3 +664,113 @@ describe("Test Basic Authentication", function() {
664664
}, "throws an exception for insecure connections");
665665
})
666666
});
667+
668+
describe("Test API Key Formatting", function() {
669+
it("Infura API Key", function() {
670+
const projectId = "someProjectId";
671+
const projectSecret = "someSecretKey";
672+
673+
// Test simple projectId
674+
const apiKeyString = ethers.providers.InfuraProvider.getApiKey(projectId);
675+
assert.equal(apiKeyString.apiKey, projectId);
676+
assert.equal(apiKeyString.projectId, projectId);
677+
assert.ok(apiKeyString.secretKey == null);
678+
679+
// Test complex API key with projectId
680+
const apiKeyObject = ethers.providers.InfuraProvider.getApiKey({
681+
projectId
682+
});
683+
assert.equal(apiKeyObject.apiKey, projectId);
684+
assert.equal(apiKeyObject.projectId, projectId);
685+
assert.ok(apiKeyObject.projectSecret == null);
686+
687+
// Test complex API key with projectId and projectSecret
688+
const apiKeyObject2 = ethers.providers.InfuraProvider.getApiKey({
689+
projectId: projectId,
690+
projectSecret: projectSecret
691+
});
692+
assert.equal(apiKeyObject2.apiKey, projectId);
693+
assert.equal(apiKeyObject2.projectId, projectId);
694+
assert.equal(apiKeyObject2.projectSecret, projectSecret);
695+
696+
// Fails on invalid projectId type
697+
assert.throws(() => {
698+
const apiKey = ethers.providers.InfuraProvider.getApiKey({
699+
projectId: 1234,
700+
projectSecret: projectSecret
701+
});
702+
console.log(apiKey);
703+
}, (error: any) => {
704+
return (error.argument === "projectId" && error.reason === "projectSecret requires a projectId");
705+
});
706+
707+
// Fails on invalid projectSecret type
708+
assert.throws(() => {
709+
const apiKey = ethers.providers.InfuraProvider.getApiKey({
710+
projectId: projectId,
711+
projectSecret: 1234
712+
});
713+
console.log(apiKey);
714+
}, (error: any) => {
715+
return (error.argument === "projectSecret" && error.reason === "invalid projectSecret");
716+
});
717+
718+
{
719+
const provider = new ethers.providers.InfuraProvider("homestead", {
720+
projectId: projectId,
721+
projectSecret: projectSecret
722+
});
723+
assert.equal(provider.network.name, "homestead");
724+
assert.equal(provider.apiKey, projectId);
725+
assert.equal(provider.projectId, projectId);
726+
assert.equal(provider.projectSecret, projectSecret);
727+
}
728+
729+
// Attempt an unsupported network
730+
assert.throws(() => {
731+
const provider = new ethers.providers.InfuraProvider("imaginary");
732+
console.log(provider);
733+
}, (error: any) => {
734+
return (error.argument === "network" && error.reason === "unsupported network");
735+
});
736+
737+
});
738+
});
739+
740+
describe("Test WebSocketProvider", function() {
741+
async function testWebSocketProvider(provider: ethers.providers.WebSocketProvider): Promise<void> {
742+
await provider.destroy();
743+
}
744+
745+
it("InfuraProvider.getWebSocketProvider", async function() {
746+
const provider = ethers.providers.InfuraProvider.getWebSocketProvider();
747+
await testWebSocketProvider(provider);
748+
});
749+
});
750+
751+
describe("Test Events", function() {
752+
async function testBlockEvent(provider: ethers.providers.Provider) {
753+
return new Promise((resolve, reject) => {
754+
let firstBlockNumber: number = null;
755+
const handler = (blockNumber: number) => {
756+
if (firstBlockNumber == null) {
757+
firstBlockNumber = blockNumber;
758+
return;
759+
}
760+
provider.removeListener("block", handler);
761+
if (firstBlockNumber + 1 === blockNumber) {
762+
resolve(true);
763+
} else {
764+
reject(new Error("blockNumber fail"));
765+
}
766+
};
767+
provider.on("block", handler);
768+
});
769+
}
770+
771+
it("InfuraProvider", async function() {
772+
this.timeout(50000);
773+
const provider = new ethers.providers.InfuraProvider("rinkeby");
774+
await testBlockEvent(provider);
775+
});
776+
});

packages/tests/src.ts/test-utils.ts

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,31 @@ describe('Test Unit Conversion', function () {
198198
}
199199
});
200200
});
201+
202+
it("formats with commify", function() {
203+
const tests: { [ testcase: string ]: string } = {
204+
"0.0": "0.0",
205+
".0": "0.0",
206+
"0.": "0.0",
207+
"00.00": "0.0",
208+
209+
"100.000": "100.0",
210+
"100.0000": "100.0",
211+
"1000.000": "1,000.0",
212+
"1000.0000": "1,000.0",
213+
214+
"100.123": "100.123",
215+
"100.1234": "100.1234",
216+
"1000.1234": "1,000.1234",
217+
"1000.12345": "1,000.12345",
218+
219+
"998998998998.123456789": "998,998,998,998.123456789",
220+
};
221+
222+
Object.keys(tests).forEach((test) => {
223+
assert.equal(ethers.utils.commify(test), tests[test]);
224+
});
225+
});
201226
});
202227

203228

@@ -216,6 +241,13 @@ describe('Test Namehash', function() {
216241
'computes namehash(' + test.name + ')');
217242
});
218243
});
244+
245+
it("isValidName", function() {
246+
assert.ok(ethers.utils.isValidName("ricmoo.eth"));
247+
248+
assert.ok(!ethers.utils.isValidName(""));
249+
assert.ok(!ethers.utils.isValidName("ricmoo..eth"));
250+
});
219251
});
220252

221253
describe('Test ID Hash Functions', function () {
@@ -255,7 +287,7 @@ describe('Test Solidity Hash Functions', function() {
255287
const tests: Array<TestCase> = loadTests('solidity-hashes');
256288

257289
function test(funcName: string, testKey: 'keccak256' | 'sha256') {
258-
it(('computes ' + funcName + ' correctly'), function() {
290+
it(`computes ${ funcName } correctly`, function() {
259291
this.timeout(120000);
260292

261293
tests.forEach((test, index) => {
@@ -269,11 +301,33 @@ describe('Test Solidity Hash Functions', function() {
269301

270302
test('Keccak256', 'keccak256');
271303
test('Sha256', 'sha256');
304+
305+
const testsInvalid = [
306+
"uint0", // number - null length
307+
"uint1", // number - not byte-aligned
308+
"uint08", // number - leading zeros
309+
"uint266", // number - out-of-range
310+
"bytes0", // bytes - null length
311+
"bytes02", // bytes - leading zeros
312+
"bytes33", // bytes - out-of-range
313+
"purple" // invalid type
314+
];
315+
316+
testsInvalid.forEach((type) => {
317+
it(`disallows invalid type "${ type }"`, function() {
318+
assert.throws(() => {
319+
ethers.utils.solidityPack([ type ], [ "0x12" ]);
320+
}, (error: Error) => {
321+
const message = error.message;
322+
return (message.match(/invalid([a-z ]*) type/) && message.indexOf(type) >= 0);
323+
});
324+
});
325+
});
272326
});
273327

274328
describe('Test Hash Functions', function() {
275329

276-
const tests: Array<{ data: string, keccak256: string, sha256: string }> = loadTests('hashes');
330+
const tests: Array<TestCase.Hash> = loadTests('hashes');
277331

278332
it('computes keccak256 correctly', function() {
279333
this.timeout(120000);
@@ -282,12 +336,19 @@ describe('Test Hash Functions', function() {
282336
});
283337
});
284338

285-
it('computes sha2566 correctly', function() {
339+
it('computes sha2-256 correctly', function() {
286340
this.timeout(120000);
287341
tests.forEach(function(test) {
288342
assert.equal(ethers.utils.sha256(test.data), test.sha256, ('SHA256 - ' + test.data));
289343
});
290344
});
345+
346+
it('computes sha2-512 correctly', function() {
347+
this.timeout(120000);
348+
tests.forEach(function(test) {
349+
assert.equal(ethers.utils.sha512(test.data), test.sha512, ('SHA512 - ' + test.data));
350+
});
351+
});
291352
});
292353

293354
describe('Test Solidity splitSignature', function() {
@@ -561,3 +622,46 @@ describe("BigNumber", function() {
561622
// @TODO: Add more tests here
562623

563624
});
625+
626+
describe("Logger", function() {
627+
const logger = new ethers.utils.Logger("testing/0.0");
628+
629+
it("checkArgumentCount", function() {
630+
logger.checkArgumentCount(3, 3);
631+
});
632+
633+
it("checkArgumentCount - too few", function() {
634+
assert.throws(() => {
635+
logger.checkArgumentCount(1, 3);
636+
}, (error: any) => {
637+
return error.code === ethers.utils.Logger.errors.MISSING_ARGUMENT;
638+
});
639+
});
640+
641+
it("checkArgumentCount - too many", function() {
642+
assert.throws(() => {
643+
logger.checkArgumentCount(3, 1);
644+
}, (error: any) => {
645+
return error.code === ethers.utils.Logger.errors.UNEXPECTED_ARGUMENT;
646+
});
647+
});
648+
});
649+
650+
/*
651+
describe("Base58 Coder", function() {
652+
it("decodes", function() {
653+
assert.equal(ethers.utils.Base58.decode("JxF12TrwUP45BMd"), "Hello World");
654+
});
655+
656+
it("encodes", function() {
657+
assert.equal(ethers.utils.Base58.encode("Hello World"), "JxF12TrwUP45BMd");
658+
});
659+
});
660+
661+
describe("Web Fetch", function() {
662+
it("fetches JSON", async function() {
663+
const url = "https:/\/api.etherscan.io/api?module=stats&action=ethprice&apikey=9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB";
664+
const getData = ethers.utils.fetchJson(url)
665+
});
666+
});
667+
*/

0 commit comments

Comments
 (0)