1
- import isValidBtcAddress from 'validator/lib/isBtcAddress' ;
2
1
import isCreditCard from 'validator/lib/isCreditCard' ;
3
2
import { describe , expect , it } from 'vitest' ;
4
3
import { faker , fakerZH_CN } from '../../src' ;
5
4
import { FakerError } from '../../src/errors/faker-error' ;
5
+ import {
6
+ BitcoinAddressFamily ,
7
+ BitcoinNetwork ,
8
+ } from '../../src/modules/finance/bitcoin' ;
6
9
import ibanLib from '../../src/modules/finance/iban' ;
7
10
import { luhnCheck } from '../../src/modules/helpers/luhn-check' ;
8
11
import { seededTests } from '../support/seeded-runs' ;
@@ -21,7 +24,6 @@ describe('finance', () => {
21
24
'currencyCode' ,
22
25
'currencyName' ,
23
26
'currencySymbol' ,
24
- 'bitcoinAddress' ,
25
27
'litecoinAddress' ,
26
28
'creditCardCVV' ,
27
29
'ethereumAddress' ,
@@ -91,6 +93,15 @@ describe('finance', () => {
91
93
ellipsis : true ,
92
94
} ) ;
93
95
} ) ;
96
+
97
+ t . describe ( 'bitcoinAddress' , ( t ) => {
98
+ t . it ( 'noArgs' )
99
+ . it ( 'with type option' , { type : BitcoinAddressFamily . Legacy } )
100
+ . it ( 'with type and network option' , {
101
+ type : BitcoinAddressFamily . Legacy ,
102
+ network : BitcoinNetwork . Mainnet ,
103
+ } ) ;
104
+ } ) ;
94
105
} ) ;
95
106
96
107
describe . each ( times ( NON_SEEDED_BASED_RUN ) . map ( ( ) => faker . seed ( ) ) ) (
@@ -313,17 +324,96 @@ describe('finance', () => {
313
324
} ) ;
314
325
315
326
describe ( 'bitcoinAddress()' , ( ) => {
327
+ const m_legacy = / ^ 1 [ A - H J - N P - Z a - k m - z 1 - 9 ] { 25 , 39 } $ / ;
328
+ const t_legacy = / ^ m [ A - H J - N P - Z a - k m - z 1 - 9 ] { 25 , 39 } $ / ;
329
+ const m_segwit = / ^ 3 [ A - H J - N P - Z a - k m - z 1 - 9 ] { 25 , 39 } $ / ;
330
+ const t_segwit = / ^ 2 [ A - H J - N P - Z a - k m - z 1 - 9 ] { 25 , 39 } $ / ;
331
+ const m_bech32 = / ^ b c 1 [ a c - h j - n p - z 0 2 - 9 ] { 39 , 39 } $ / ;
332
+ const t_bech32 = / ^ t b 1 [ a c - h j - n p - z 0 2 - 9 ] { 39 , 39 } $ / ;
333
+ const m_taproot = / ^ b c 1 p [ a c - h j - n p - z 0 2 - 9 ] { 58 , 58 } $ / ;
334
+ const t_taproot = / ^ t b 1 p [ a c - h j - n p - z 0 2 - 9 ] { 58 , 58 } $ / ;
335
+
336
+ const isBtcAddress = ( address : string ) =>
337
+ [
338
+ m_legacy ,
339
+ t_legacy ,
340
+ m_segwit ,
341
+ t_segwit ,
342
+ m_bech32 ,
343
+ t_bech32 ,
344
+ m_taproot ,
345
+ t_taproot ,
346
+ ] . some ( ( r ) => r . test ( address ) ) ;
347
+
316
348
it ( 'should return a valid bitcoin address' , ( ) => {
317
349
const bitcoinAddress = faker . finance . bitcoinAddress ( ) ;
318
- /**
319
- * Note: Although the total length of a Bitcoin address can be 25-33 characters, regex quantifiers only check the preceding token
320
- * Therefore we take one from the total length of the address not including the first character ([13])
321
- */
322
350
323
351
expect ( bitcoinAddress ) . toBeTruthy ( ) ;
324
352
expect ( bitcoinAddress ) . toBeTypeOf ( 'string' ) ;
325
- expect ( bitcoinAddress ) . toSatisfy ( isValidBtcAddress ) ;
326
- } ) ;
353
+ expect ( bitcoinAddress ) . toSatisfy ( isBtcAddress ) ;
354
+ } ) ;
355
+
356
+ it . each ( [
357
+ [ BitcoinAddressFamily . Legacy , m_legacy ] ,
358
+ [ BitcoinAddressFamily . Segwit , m_segwit ] ,
359
+ [ BitcoinAddressFamily . Bech32 , m_bech32 ] ,
360
+ [ BitcoinAddressFamily . Taproot , m_taproot ] ,
361
+ ] as const ) (
362
+ 'should handle the type = $type argument' ,
363
+ ( type , regex ) => {
364
+ const bitcoinAddress = faker . finance . bitcoinAddress ( {
365
+ type,
366
+ } ) ;
367
+
368
+ expect ( bitcoinAddress ) . toBeTruthy ( ) ;
369
+ expect ( bitcoinAddress ) . toBeTypeOf ( 'string' ) ;
370
+ expect ( bitcoinAddress ) . toSatisfy ( isBtcAddress ) ;
371
+ expect ( bitcoinAddress ) . toMatch ( regex ) ;
372
+ }
373
+ ) ;
374
+
375
+ it . each ( [
376
+ [ BitcoinNetwork . Mainnet , [ m_legacy , m_segwit , m_bech32 , m_taproot ] ] ,
377
+ [ BitcoinNetwork . Testnet , [ t_legacy , t_segwit , t_bech32 , t_taproot ] ] ,
378
+ ] as const ) (
379
+ 'should handle the network = $network argument' ,
380
+ ( network , regexes ) => {
381
+ const bitcoinAddress = faker . finance . bitcoinAddress ( {
382
+ network,
383
+ } ) ;
384
+
385
+ expect ( bitcoinAddress ) . toBeTruthy ( ) ;
386
+ expect ( bitcoinAddress ) . toBeTypeOf ( 'string' ) ;
387
+ expect ( bitcoinAddress ) . toSatisfy ( isBtcAddress ) ;
388
+ expect ( bitcoinAddress ) . toSatisfy < string > ( ( v ) =>
389
+ regexes . some ( ( r ) => r . test ( v ) )
390
+ ) ;
391
+ }
392
+ ) ;
393
+
394
+ it . each ( [
395
+ [ BitcoinAddressFamily . Legacy , BitcoinNetwork . Mainnet , m_legacy ] ,
396
+ [ BitcoinAddressFamily . Legacy , BitcoinNetwork . Testnet , t_legacy ] ,
397
+ [ BitcoinAddressFamily . Segwit , BitcoinNetwork . Mainnet , m_segwit ] ,
398
+ [ BitcoinAddressFamily . Segwit , BitcoinNetwork . Testnet , t_segwit ] ,
399
+ [ BitcoinAddressFamily . Bech32 , BitcoinNetwork . Mainnet , m_bech32 ] ,
400
+ [ BitcoinAddressFamily . Bech32 , BitcoinNetwork . Testnet , t_bech32 ] ,
401
+ [ BitcoinAddressFamily . Taproot , BitcoinNetwork . Mainnet , m_taproot ] ,
402
+ [ BitcoinAddressFamily . Taproot , BitcoinNetwork . Testnet , t_taproot ] ,
403
+ ] as const ) (
404
+ 'should handle the type = $type and network = $network arguments' ,
405
+ ( type , network , regex ) => {
406
+ const bitcoinAddress = faker . finance . bitcoinAddress ( {
407
+ type,
408
+ network,
409
+ } ) ;
410
+
411
+ expect ( bitcoinAddress ) . toBeTruthy ( ) ;
412
+ expect ( bitcoinAddress ) . toBeTypeOf ( 'string' ) ;
413
+ expect ( bitcoinAddress ) . toSatisfy ( isBtcAddress ) ;
414
+ expect ( bitcoinAddress ) . toMatch ( regex ) ;
415
+ }
416
+ ) ;
327
417
} ) ;
328
418
329
419
describe ( 'litecoinAddress()' , ( ) => {
0 commit comments