Skip to content

Commit 47dc824

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): replace shouldjs with node:assert
Replace shouldjs assertions with Node.js native assert/strict throughout the abstract-utxo module test suite. This modernizes testing infrastructure and eliminates a deprecated dependency. Main changes: - Switch to node:assert/strict for all assertions - Add helper functions: `assertHasProperty`, `assertContains`, `assertEqualJSON` - Add `isPsbt` utility function for checking PSBT magic bytes - Update Sinon assertion syntax to use `sinon.assert.*` methods - Simplify assertion patterns across unit and integration tests Issue: BTC-2768 Co-authored-by: llm-git <llm-git@ttll.de>
1 parent e496856 commit 47dc824

21 files changed

Lines changed: 282 additions & 271 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { hasPsbtMagic } from '@bitgo/wasm-utxo';
2+
3+
/**
4+
* Check if a hex string or buffer contains PSBT data by checking for PSBT magic bytes.
5+
*/
6+
export function isPsbt(data: Buffer | string): boolean {
7+
const buf = typeof data === 'string' ? Buffer.from(data, 'hex') : data;
8+
return hasPsbtMagic(buf);
9+
}

modules/abstract-utxo/test/integration/impl/bch/bch.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as should from 'should';
2-
import 'should-http';
1+
import assert from 'node:assert/strict';
2+
33
import { BitGoAPI } from '@bitgo/sdk-api';
44
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
55
import * as nock from 'nock';
@@ -34,13 +34,13 @@ describe('BCH:', function () {
3434
otp: bitgo.testUserOTP(),
3535
});
3636

37-
should.exist(transaction);
38-
transaction.should.have.property('transfer');
39-
transaction.should.have.property('txid');
40-
transaction.should.have.property('tx');
41-
transaction.status.should.containEql('signed');
42-
transaction.transfer.type.should.containEql('send');
43-
transaction.transfer.wallet.should.containEql(wallet._wallet.id);
37+
assert.ok(transaction != null);
38+
assert.ok('transfer' in transaction);
39+
assert.ok('txid' in transaction);
40+
assert.ok('tx' in transaction);
41+
assert.ok(transaction.status.includes('signed'));
42+
assert.ok(transaction.transfer.type.includes('send'));
43+
assert.ok(transaction.transfer.wallet.includes(wallet._wallet.id));
4444
});
4545
});
4646
});

modules/abstract-utxo/test/unit/customSigner.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import * as utxoLib from '@bitgo/utxo-lib';
2-
import 'should';
3-
import 'should-sinon';
42
import nock = require('nock');
53
import * as sinon from 'sinon';
64
import { CustomSigningFunction, common } from '@bitgo/sdk-core';
75

8-
import { defaultBitGo, getDefaultWalletKeys, getUtxoCoin, getUtxoWallet } from './util';
6+
import { defaultBitGo, getDefaultWalletKeys, getUtxoCoin, getUtxoWallet, assertHasProperty } from './util';
97

108
nock.disableNetConnect();
119

@@ -65,8 +63,8 @@ describe('UTXO Custom Signer Function', function () {
6563
const scope = nocks({ txHex: psbt.toHex() });
6664
const result = await wallet.sendMany({ recipients, customSigningFunction });
6765

68-
result.should.have.property('ok', true);
69-
customSigningFunction.should.have.been.calledTwice();
66+
assertHasProperty(result, 'ok', true);
67+
sinon.assert.calledTwice(customSigningFunction as sinon.SinonStub);
7068
scope.done();
7169
});
7270

@@ -81,8 +79,8 @@ describe('UTXO Custom Signer Function', function () {
8179
const scope = nocks({ txHex: psbt.toHex() });
8280
const result = await wallet.sendMany({ recipients, customSigningFunction });
8381

84-
result.should.have.property('ok', true);
85-
customSigningFunction.should.have.been.calledOnce();
82+
assertHasProperty(result, 'ok', true);
83+
sinon.assert.calledOnce(customSigningFunction as sinon.SinonStub);
8684
scope.done();
8785
});
8886

@@ -97,8 +95,8 @@ describe('UTXO Custom Signer Function', function () {
9795
const scope = nocks({ txHex: tx.buildIncomplete().toHex() });
9896
const result = await wallet.sendMany({ recipients, customSigningFunction });
9997

100-
result.should.have.property('ok', true);
101-
customSigningFunction.should.have.been.calledOnce();
98+
assertHasProperty(result, 'ok', true);
99+
sinon.assert.calledOnce(customSigningFunction as sinon.SinonStub);
102100
scope.done();
103101
});
104102
});
Lines changed: 104 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
import assert from 'node:assert/strict';
2+
13
import { BitGoAPI } from '@bitgo/sdk-api';
24
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
35

46
import { Bch, Tbch } from '../../../../../src/impl/bch';
57

8+
function eq(actual: string, expected: string) {
9+
assert.strictEqual(actual, expected);
10+
}
11+
612
describe('Custom BCH Tests', function () {
713
const bitgo: TestBitGoAPI = TestBitGo.decorate(BitGoAPI, { env: 'test' });
814
bitgo.initializeTestVars();
@@ -15,145 +21,117 @@ describe('Custom BCH Tests', function () {
1521
// we use mainnet bch so we can reuse the mainnet address examples
1622
it('should correctly convert addresses', function () {
1723
// P2PKH cashaddr -> cashaddr
18-
bch
19-
.canonicalAddress('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr')
20-
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');
21-
bch
22-
.canonicalAddress('qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr')
23-
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');
24-
24+
eq(
25+
bch.canonicalAddress('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'),
26+
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
27+
);
28+
eq(
29+
bch.canonicalAddress('qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'),
30+
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
31+
);
2532
// P2PKH base58 -> cashaddr
26-
bch
27-
.canonicalAddress('1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu', 'cashaddr')
28-
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');
29-
33+
eq(
34+
bch.canonicalAddress('1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu', 'cashaddr'),
35+
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
36+
);
3037
// P2SH cashaddr -> cashaddr
31-
bch
32-
.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
33-
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');
34-
bch
35-
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
36-
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');
37-
38+
eq(
39+
bch.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
40+
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
41+
);
42+
eq(
43+
bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
44+
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
45+
);
3846
// P2SH base58 -> cashaddr
39-
bch
40-
.canonicalAddress('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC', 'cashaddr')
41-
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');
42-
47+
eq(
48+
bch.canonicalAddress('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC', 'cashaddr'),
49+
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
50+
);
4351
// no 'bitcoincash:' prefix
44-
bch
45-
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
46-
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');
47-
52+
eq(
53+
bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
54+
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
55+
);
4856
// P2PKH cashaddr -> base58
49-
bch
50-
.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58')
51-
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
52-
bch
53-
.canonicalAddress('qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58')
54-
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
55-
57+
eq(
58+
bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58'),
59+
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
60+
);
61+
eq(
62+
bch.canonicalAddress('qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58'),
63+
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
64+
);
5665
// P2PKH base58 -> base58
57-
bch
58-
.canonicalAddress('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb', 'base58')
59-
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
60-
66+
eq(bch.canonicalAddress('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb', 'base58'), '16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
6167
// P2SH cashaddr -> base58
62-
bch
63-
.canonicalAddress('bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
64-
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
65-
bch
66-
.canonicalAddress('pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
67-
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
68-
68+
eq(
69+
bch.canonicalAddress('bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'),
70+
'3LDsS579y7sruadqu11beEJoTjdFiFCdX4'
71+
);
72+
eq(
73+
bch.canonicalAddress('pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'),
74+
'3LDsS579y7sruadqu11beEJoTjdFiFCdX4'
75+
);
6976
// P2SH base58 -> base58
70-
bch
71-
.canonicalAddress('3LDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58')
72-
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
73-
77+
eq(bch.canonicalAddress('3LDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58'), '3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
7478
// undefined version defaults to base58
75-
bch
76-
.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq')
77-
.should.equal('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');
78-
bch
79-
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq')
80-
.should.equal('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');
81-
79+
eq(
80+
bch.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'),
81+
'3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC'
82+
);
83+
eq(bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'), '3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');
8284
// all capitalized
83-
bch
84-
.canonicalAddress('BITCOINCASH:QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58')
85-
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
86-
bch
87-
.canonicalAddress('QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58')
88-
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
89-
85+
eq(
86+
bch.canonicalAddress('BITCOINCASH:QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58'),
87+
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
88+
);
89+
eq(
90+
bch.canonicalAddress('QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58'),
91+
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
92+
);
9093
// testnet addresses
91-
tbch
92-
.canonicalAddress('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X', 'cashaddr')
93-
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
94-
tbch
95-
.canonicalAddress('n3jYBjCzgGNydQwf83Hz6GBzGBhMkKfgL1', 'cashaddr')
96-
.should.equal('bchtest:qremgr9dr9x5swv82k69qdjzrvdxgkaaesftdp5xla');
97-
tbch
98-
.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
99-
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
100-
tbch
101-
.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
102-
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
103-
tbch
104-
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58')
105-
.should.equal('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X');
106-
tbch
107-
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58')
108-
.should.equal('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X');
109-
tbch
110-
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
111-
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
94+
eq(
95+
tbch.canonicalAddress('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X', 'cashaddr'),
96+
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
97+
);
98+
eq(
99+
tbch.canonicalAddress('n3jYBjCzgGNydQwf83Hz6GBzGBhMkKfgL1', 'cashaddr'),
100+
'bchtest:qremgr9dr9x5swv82k69qdjzrvdxgkaaesftdp5xla'
101+
);
102+
eq(
103+
tbch.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
104+
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
105+
);
106+
eq(
107+
tbch.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
108+
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
109+
);
110+
eq(
111+
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58'),
112+
'2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'
113+
);
114+
eq(
115+
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58'),
116+
'2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'
117+
);
118+
eq(
119+
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
120+
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
121+
);
112122
});
113123

114124
it('should reject invalid addresses', function () {
115-
// improperly short data segment
116-
(() => {
117-
bch.canonicalAddress('bitcoincash:sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
118-
}).should.throw();
119-
120-
// mismatched data segment (cashaddr)
121-
(() => {
122-
bch.canonicalAddress('bitcoincash:yr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
123-
}).should.throw();
124-
125-
// double prefix
126-
(() => {
127-
bch.canonicalAddress('bitcoincash:bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
128-
}).should.throw();
129-
130-
// mismatched data segment (base58)
131-
(() => {
132-
bch.canonicalAddress('3DDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58');
133-
}).should.throw();
134-
135-
// improper prefix
136-
(() => {
137-
bch.canonicalAddress(':qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58');
138-
}).should.throw();
139-
140-
(() => {
141-
bch.canonicalAddress('bitcoin:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58');
142-
}).should.throw();
143-
144-
// mismatched capitalization
145-
(() => {
146-
bch.canonicalAddress('bitcoincash:QPM2Qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr');
147-
}).should.throw();
148-
149-
// improper version
150-
(() => {
151-
bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'blah');
152-
}).should.throw();
153-
154-
// undefined address
155-
(() => {
156-
bch.canonicalAddress(undefined as any, 'blah');
157-
}).should.throw();
125+
assert.throws(() => bch.canonicalAddress('bitcoincash:sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'));
126+
assert.throws(() => bch.canonicalAddress('bitcoincash:yr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'));
127+
assert.throws(() =>
128+
bch.canonicalAddress('bitcoincash:bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
129+
);
130+
assert.throws(() => bch.canonicalAddress('3DDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58'));
131+
assert.throws(() => bch.canonicalAddress(':qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58'));
132+
assert.throws(() => bch.canonicalAddress('bitcoin:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58'));
133+
assert.throws(() => bch.canonicalAddress('bitcoincash:QPM2Qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'));
134+
assert.throws(() => bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'blah'));
135+
assert.throws(() => bch.canonicalAddress(undefined as any, 'blah'));
158136
});
159137
});

0 commit comments

Comments
 (0)