Skip to content

Commit eb24526

Browse files
committed
Replacing jest with mocha
1 parent 21cf8ea commit eb24526

15 files changed

+4582
-4620
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
**/node_modules
66
**/target
77
**/dist
8+
**/tmp
89
storage*/
910
**/.next
1011

@@ -18,4 +19,4 @@ rust/src/program/.DS_Store
1819
# Local Netlify folder
1920
.netlify
2021

21-
package-lock.json
22+
package-lock.json

sdk/jest-config.json

-9
This file was deleted.

sdk/jest-integration-config.json

-9
This file was deleted.

sdk/package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
"scripts": {
3232
"build": "rimraf dist && rollup -c rollup.config.js",
3333
"prepublish": "yarn build",
34-
"test": "node --no-warnings --experimental-vm-modules ../node_modules/jest/bin/jest.js --config jest-config.json --detectOpenHandles",
35-
"integration": "node --no-warnings --experimental-vm-modules ../node_modules/jest/bin/jest.js --silent=false --runInBand --detectOpenHandles",
36-
"clear_jest": "jest --clearCache"
34+
"test": "rimraf tmp && rollup -c rollup.test.js && mocha tmp/**/*.test.js --parallel --timeout 60000"
3735
},
3836
"repository": {
3937
"type": "git",
@@ -57,24 +55,27 @@
5755
},
5856
"devDependencies": {
5957
"@rollup/plugin-replace": "^5.0.5",
60-
"@types/jest": "^29.5.5",
58+
"@types/chai": "^4.3.16",
6159
"@types/mime": "^3.0.1",
60+
"@types/sinon": "^17.0.3",
6261
"@typescript-eslint/eslint-plugin": "^5.41.0",
6362
"@typescript-eslint/parser": "^5.41.0",
6463
"better-docs": "^2.7.2",
64+
"chai": "^5.1.1",
6565
"clean-jsdoc-theme": "^4.1.8",
6666
"core-js": "^3.38.1",
6767
"cpr": "^3.0.1",
6868
"eslint": "^8.26.0",
6969
"eslint-config-prettier": "^8.5.0",
7070
"eslint-plugin-import": "^2.26.0",
71-
"jest": "^29.7.0",
71+
"glob": "^11.0.0",
7272
"jsdoc": "^3.6.11",
73+
"mocha": "^10.7.0",
7374
"prettier": "2.7.1",
7475
"rimraf": "^5.0.1",
7576
"rollup": "^3.27.2",
7677
"rollup-plugin-typescript2": "^0.36.0",
77-
"ts-jest": "^29.1.1",
78+
"sinon": "^18.0.0",
7879
"typescript": "^5.2.2"
7980
}
8081
}

sdk/rollup.test.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import typescript from "rollup-plugin-typescript2";
2+
import replace from "@rollup/plugin-replace";
3+
import { globSync } from "glob";
4+
import $package from "./package.json" assert { type: "json" };
5+
6+
const networks = [
7+
"testnet",
8+
//"mainnet",
9+
];
10+
11+
function inputs() {
12+
const files = {};
13+
14+
globSync("./tests/**/*.ts").forEach((x) => {
15+
files[x.replace(/\.[^\.]+$/, "")] = x;
16+
});
17+
18+
return files;
19+
}
20+
21+
export default networks.map((network) => {
22+
return {
23+
input: inputs(),
24+
output: {
25+
dir: `tmp/${network}`,
26+
chunkFileNames: "[name].js",
27+
format: "es",
28+
sourcemap: true,
29+
},
30+
external: [
31+
// Used by node-polyfill
32+
"node:worker_threads",
33+
"node:os",
34+
"node:fs",
35+
"node:crypto",
36+
"mime/lite.js",
37+
"sync-request",
38+
39+
// Used by the SDK
40+
"comlink",
41+
`@provablehq/wasm/${network}.js`,
42+
],
43+
plugins: [
44+
replace({
45+
preventAssignment: true,
46+
delimiters: ['', ''],
47+
values: {
48+
'%%VERSION%%': $package.version,
49+
'%%NETWORK%%': network,
50+
},
51+
}),
52+
typescript({
53+
tsconfig: "tsconfig.test.json",
54+
clean: true,
55+
}),
56+
],
57+
};
58+
});

sdk/tests/account.test.ts

+79-72
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,71 @@
1-
import {jest} from '@jest/globals'
2-
import { Account, Address, PrivateKey, RecordCiphertext, ViewKey } from '../src/node'
3-
import { seed, message, beaconPrivateKeyString, beaconViewKeyString, beaconAddressString, recordCiphertextString, foreignCiphertextString, recordPlaintextString } from './data/account-data';
4-
1+
import sinon from "sinon";
2+
import { expect } from "chai";
3+
import { Account, Address, PrivateKey, RecordCiphertext, ViewKey } from "../src/node";
4+
import { seed, message, beaconPrivateKeyString, beaconViewKeyString, beaconAddressString, recordCiphertextString, foreignCiphertextString, recordPlaintextString } from "./data/account-data";
55

66
describe('Account', () => {
7+
afterEach(() => {
8+
sinon.restore();
9+
});
10+
711
describe('constructors', () => {
8-
test('creates a new account if no parameters are passed', () => {
12+
it('creates a new account if no parameters are passed', () => {
913
// Generate account from rng
1014
const account = new Account();
1115

1216
// Test object member type consistency
13-
expect(account._privateKey).toBeInstanceOf(PrivateKey);
14-
expect(account._viewKey).toBeInstanceOf(ViewKey);
15-
expect(account._address).toBeInstanceOf(Address);
17+
expect(account._privateKey).instanceof(PrivateKey);
18+
expect(account._viewKey).instanceof(ViewKey);
19+
expect(account._address).instanceof(Address);
1620
// Test convenience method type consistency
17-
expect(account.privateKey()).toBeInstanceOf(PrivateKey);
18-
expect(account.viewKey()).toBeInstanceOf(ViewKey);
19-
expect(account.address()).toBeInstanceOf(Address);
21+
expect(account.privateKey()).instanceof(PrivateKey);
22+
expect(account.viewKey()).instanceof(ViewKey);
23+
expect(account.address()).instanceof(Address);
2024
});
2125

22-
test('creates a new from seed', () => {
26+
it('creates a new from seed', () => {
2327
// Generate account from a seed
2428
const account = new Account({seed: seed});
2529

2630
// Test object member type consistency
27-
expect(account._privateKey).toBeInstanceOf(PrivateKey);
28-
expect(account._viewKey).toBeInstanceOf(ViewKey);
29-
expect(account._address).toBeInstanceOf(Address);
31+
expect(account._privateKey).instanceof(PrivateKey);
32+
expect(account._viewKey).instanceof(ViewKey);
33+
expect(account._address).instanceof(Address);
3034
// Test convenience method type consistency
31-
expect(account.privateKey()).toBeInstanceOf(PrivateKey);
32-
expect(account.viewKey()).toBeInstanceOf(ViewKey);
33-
expect(account.address()).toBeInstanceOf(Address);
35+
expect(account.privateKey()).instanceof(PrivateKey);
36+
expect(account.viewKey()).instanceof(ViewKey);
37+
expect(account.address()).instanceof(Address);
3438
// Test that expected output is generated
35-
expect(account.privateKey().to_string()).toEqual(beaconPrivateKeyString);
36-
expect(account.viewKey().to_string()).toEqual(beaconViewKeyString);
37-
expect(account.address().to_string()).toEqual(beaconAddressString);
38-
expect(account.toString()).toEqual(beaconAddressString);
39+
expect(account.privateKey().to_string()).equal(beaconPrivateKeyString);
40+
expect(account.viewKey().to_string()).equal(beaconViewKeyString);
41+
expect(account.address().to_string()).equal(beaconAddressString);
42+
expect(account.toString()).equal(beaconAddressString);
3943
});
4044

41-
test('throws an error if parameters are invalid', () => {
42-
expect(() => new Account({privateKey: 'invalidPrivateKey'})).toThrow();
45+
it('throws an error if parameters are invalid', () => {
46+
expect(() => new Account({privateKey: 'invalidPrivateKey'})).throw();
4347
});
4448

45-
test('creates an account object from a valid private key string', () => {
49+
it('creates an account object from a valid private key string', () => {
4650
// Generate account from valid private key string
4751
const account = new Account( {privateKey: beaconPrivateKeyString});
4852

4953
// Test object member type consistency
50-
expect(account._privateKey).toBeInstanceOf(PrivateKey);
51-
expect(account._viewKey).toBeInstanceOf(ViewKey);
52-
expect(account._address).toBeInstanceOf(Address);
54+
expect(account._privateKey).instanceof(PrivateKey);
55+
expect(account._viewKey).instanceof(ViewKey);
56+
expect(account._address).instanceof(Address);
5357
// Test convenience method type consistency
54-
expect(account.privateKey()).toBeInstanceOf(PrivateKey);
55-
expect(account.viewKey()).toBeInstanceOf(ViewKey);
56-
expect(account.address()).toBeInstanceOf(Address);
58+
expect(account.privateKey()).instanceof(PrivateKey);
59+
expect(account.viewKey()).instanceof(ViewKey);
60+
expect(account.address()).instanceof(Address);
5761
// Test that expected output is generated
58-
expect(account.privateKey().to_string()).toEqual(beaconPrivateKeyString);
59-
expect(account.viewKey().to_string()).toEqual(beaconViewKeyString);
60-
expect(account.address().to_string()).toEqual(beaconAddressString);
61-
expect(account.toString()).toEqual(beaconAddressString);
62+
expect(account.privateKey().to_string()).equal(beaconPrivateKeyString);
63+
expect(account.viewKey().to_string()).equal(beaconViewKeyString);
64+
expect(account.address().to_string()).equal(beaconAddressString);
65+
expect(account.toString()).equal(beaconAddressString);
6266
});
6367

64-
test('can encrypt an account and decrypt to the same account', () => {
68+
it('can encrypt an account and decrypt to the same account', () => {
6569
const newAccount = new Account();
6670
const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
6771
const privateKeyCiphertextString = privateKeyCiphertext.toString();
@@ -72,14 +76,14 @@ describe('Account', () => {
7276

7377
for (const account of [accountFromString, accountFromObject]) {
7478
// Test that expected output is generated
75-
expect(account.privateKey().to_string()).toEqual(newAccount.privateKey().to_string());
76-
expect(account.viewKey().to_string()).toEqual(newAccount.viewKey().to_string());
77-
expect(account.address().to_string()).toEqual(newAccount.toString());
78-
expect(account.toString()).toEqual(newAccount.toString());
79+
expect(account.privateKey().to_string()).equal(newAccount.privateKey().to_string());
80+
expect(account.viewKey().to_string()).equal(newAccount.viewKey().to_string());
81+
expect(account.address().to_string()).equal(newAccount.toString());
82+
expect(account.toString()).equal(newAccount.toString());
7983
}
8084
});
8185

82-
test('fails to create an account from a bad password', () => {
86+
it('fails to create an account from a bad password', () => {
8387
const newAccount = new Account();
8488
const privateKeyCiphertext = newAccount.encryptAccount("mypassword");
8589
const privateKeyCiphertextString = privateKeyCiphertext.toString();
@@ -89,28 +93,30 @@ describe('Account', () => {
8993
Account.fromCiphertext(privateKeyCiphertext, "badpassword");
9094

9195
// Should not get here
92-
expect(true).toBe(false);
96+
expect(true).equal(false);
9397
} catch (err) {
9498
// The account should fail to decrypt
95-
expect(true).toBe(true);
99+
expect(true).equal(true);
96100
}
97101
});
98102
});
99103

100104
describe('View Key Record Decryption', () => {
101-
test('decrypts a record in ciphertext form', () => {
105+
it('decrypts a record in ciphertext form', () => {
102106
const account = new Account({privateKey: "APrivateKey1zkpJkyYRGYtkeHDaFfwsKtUJzia7csiWhfBWPXWhXJzy9Ls"});
103-
const decrypt_spy = jest.spyOn(account._viewKey, 'decrypt');
107+
108+
const decrypt_spy = sinon.spy(account._viewKey, 'decrypt');
109+
104110
// Decrypt record the private key owns
105111
const decryptedRecord = account.decryptRecord(recordCiphertextString);
106112

107113
// Ensure the underlying wasm is being called with the right data
108-
expect(decrypt_spy).toHaveBeenCalledWith(recordCiphertextString);
114+
expect(decrypt_spy.calledWith(recordCiphertextString)).equal(true);
109115
// Ensure it decrypts to the correct data
110-
expect(decryptedRecord).toBe(recordPlaintextString);
116+
expect(decryptedRecord).equal(recordPlaintextString);
111117
});
112118

113-
test('doesnt decrypt records from other accounts nor identifies them as the record owner', () => {
119+
it('doesnt decrypt records from other accounts nor identifies them as the record owner', () => {
114120
function tryDecrypt() {
115121
try {
116122
return account.decryptRecord(foreignCiphertextString);
@@ -119,62 +125,63 @@ describe('Account', () => {
119125
}
120126
}
121127
const account = new Account({privateKey: "APrivateKey1zkpJkyYRGYtkeHDaFfwsKtUJzia7csiWhfBWPXWhXJzy9Ls"});
122-
const decrypt_spy = jest.spyOn(account._viewKey, 'decrypt');
128+
const decrypt_spy = sinon.spy(account._viewKey, 'decrypt');
123129
const recordCiphertext = RecordCiphertext.fromString(foreignCiphertextString);
124130

125131
// Ensure a foreign record decryption attempt throws
126-
expect(tryDecrypt).toThrow();
132+
expect(tryDecrypt).throw();
127133
// Ensure the underlying wasm is being called with the right data
128-
expect(decrypt_spy).toHaveBeenCalledWith(foreignCiphertextString);
134+
expect(decrypt_spy.calledWith(foreignCiphertextString)).equal(true);
129135
// Ensure the account doesn't identify the record ciphertext as its own from both string and object forms
130-
expect(account.ownsRecordCiphertext(foreignCiphertextString)).toBe(false);
131-
expect(account.ownsRecordCiphertext(recordCiphertext)).toBe(false);
136+
expect(account.ownsRecordCiphertext(foreignCiphertextString)).equal(false);
137+
expect(account.ownsRecordCiphertext(recordCiphertext)).equal(false);
132138

133139
});
134140

135-
test('decrypts an array of records in ciphertext form', () => {
141+
it('decrypts an array of records in ciphertext form', () => {
136142
const account = new Account({privateKey: "APrivateKey1zkpJkyYRGYtkeHDaFfwsKtUJzia7csiWhfBWPXWhXJzy9Ls"});
137143
const ciphertexts = [recordCiphertextString, recordCiphertextString];
138-
const decrypt_spy = jest.spyOn(account._viewKey, 'decrypt');
144+
const decrypt_spy = sinon.spy(account._viewKey, 'decrypt');
139145
const decryptedRecords = account.decryptRecords(ciphertexts);
140146

141147
// Ensure the right number of calls were called and right inputs were passed
142-
expect(decrypt_spy).toHaveBeenCalledTimes(2);
143-
expect(decrypt_spy).toHaveBeenCalledWith(ciphertexts[0]);
144-
expect(decrypt_spy).toHaveBeenCalledWith(ciphertexts[1]);
148+
expect(decrypt_spy.callCount).equal(2);
149+
expect(decrypt_spy.calledWith(ciphertexts[0])).equal(true);
150+
expect(decrypt_spy.calledWith(ciphertexts[1])).equal(true);
145151
// Ensure the records were decrypted to the correct data
146-
expect(decryptedRecords).toEqual([recordPlaintextString, recordPlaintextString]);
152+
expect(decryptedRecords).deep.equal([recordPlaintextString, recordPlaintextString]);
147153
});
148154
});
149155

150156
describe('Sign and Verify', () => {
151157

152-
test("verifies the signature on a message", () => {
158+
it("verifies the signature on a message", () => {
153159
const account = new Account();
154160
const other_message = Uint8Array.from([104, 101, 108, 108, 111, 32, 120, 121, 114, 108, 99]);
155-
const sign_spy = jest.spyOn(account._privateKey, 'sign');
161+
const sign_spy = sinon.spy(account._privateKey, 'sign');
156162
const signature = account.sign(message);
157163

158164
// Ensure the signature was called with the right message
159-
expect(sign_spy).lastCalledWith(message);
165+
expect(sign_spy.calledWith(message)).equal(true);
160166
const other_signature = account.sign(other_message);
161167
// Ensure the signature was called with the right message and the right number of times
162-
expect(sign_spy).lastCalledWith(other_message);
163-
expect(sign_spy).toHaveBeenCalledTimes(2);
164-
const verify_spy = jest.spyOn(account._address, 'verify');
168+
expect(sign_spy.calledWith(other_message)).equal(true);
169+
expect(sign_spy.callCount).equal(2);
170+
171+
const verify_spy = sinon.spy(account._address, 'verify');
165172
const isValid = account.verify(message, signature);
166-
expect(verify_spy).lastCalledWith(message, signature);
173+
expect(verify_spy.calledWith(message, signature)).equal(true);
167174
const isSigValidForWrongMessage = account.verify(other_message, signature);
168-
expect(verify_spy).lastCalledWith(other_message, signature);
175+
expect(verify_spy.calledWith(other_message, signature)).equal(true);
169176
const isSigValidForMultipleMessages = account.verify(other_message, other_signature);
170-
expect(verify_spy).lastCalledWith(other_message, other_signature);
171-
expect(verify_spy).toHaveBeenCalledTimes(3);
177+
expect(verify_spy.calledWith(other_message, other_signature)).equal(true);
178+
expect(verify_spy.callCount).equal(3);
172179
// Ensure the signature was valid
173-
expect(isValid).toBe(true);
180+
expect(isValid).equal(true);
174181
// Ensure the second message was valid
175-
expect(isSigValidForMultipleMessages).toBe(true);
182+
expect(isSigValidForMultipleMessages).equal(true);
176183
// Ensure a signature & message mismatch is invalid
177-
expect(isSigValidForWrongMessage).toBe(false);
184+
expect(isSigValidForWrongMessage).equal(false);
178185
});
179186
});
180187
});

0 commit comments

Comments
 (0)