Skip to content

Commit f3fb730

Browse files
author
Dmitry Ovsyanko
committed
CadNum
1 parent 2e2ab61 commit f3fb730

File tree

6 files changed

+236
-276
lines changed

6 files changed

+236
-276
lines changed

.github/workflows/main.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
name: unit tests
2-
on: push
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
branches:
8+
- main
39
jobs:
410
build:
511
runs-on: ubuntu-latest

__tests__/isCadNum.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const {isCadNum, randomCadNum} = require ('..')
2+
3+
const RE = /^\d{2}:\d{2}:\d{6,7}:\d{1,}$/
4+
5+
test ('basic', () => {
6+
7+
expect (() => isCadNum ()).toThrow ()
8+
expect (() => isCadNum (123)).toThrow ()
9+
10+
expect (() => isCadNum ('47:14:120300:')).toThrow ()
11+
expect (() => isCadNum ('47:14:12030:814')).toThrow ()
12+
expect (() => isCadNum ('47:14:12030011:814')).toThrow ()
13+
14+
expect (() => isCadNum ('47-14-120300-814')).toThrow ()
15+
16+
expect (() => isCadNum ('47!14:120300:814')).toThrow ()
17+
expect (() => isCadNum ('47:14-1203001:814')).toThrow ()
18+
19+
expect (() => isCadNum ('47:14:12030O:814')).toThrow ()
20+
expect (() => isCadNum ('47:14:1203001:81A')).toThrow ()
21+
22+
expect (isCadNum ('47:14:120300:814')).toBeUndefined ()
23+
expect (isCadNum ('47:14:1203001:814')).toBeUndefined ()
24+
25+
for (const pre of [undefined, '', '47', '47:', '47:14', '47:14', '47:14:120300', '47:14:1203001', '47:14:120300:', '47:14:1203001:']) {
26+
27+
for (const length of [undefined, 14, 18]) {
28+
29+
for (let i = 0; i < 10; i ++) {
30+
31+
const v = randomCadNum (pre || length ? {pre, length} : undefined)
32+
33+
expect (v).toMatch (RE)
34+
if (pre && length > pre.length + 2) {
35+
expect (v).toMatch (pre)
36+
expect (v).toHaveLength (length)
37+
}
38+
39+
}
40+
41+
}
42+
43+
}
44+
45+
})

index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {INN_10, INN_12_2, INN_12_1} = require ('./lib/INN')
44
const SNILS = require ('./lib/SNILS')
55
const BankAcct = require ('./lib/BankAcct')
66
const BankCard = require ('./lib/BankCard')
7+
const CadNum = require ('./lib/CadNum'), cadNum = new CadNum ()
78
const {OKPO_8, OKPO_10} = require ('./lib/OKPO')
89
class KPP extends Check {constructor () {super (9)}}
910

@@ -42,4 +43,7 @@ module.exports = {
4243
isBankCard : str => new BankCard ().verify (str),
4344
randomBankCard : opt => new BankCard ().random (opt),
4445

46+
isCadNum : str => cadNum.verify (str),
47+
randomCadNum : opt => cadNum.random (opt),
48+
4549
}

lib/CadNum.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
const CH_COLON = ':'.charCodeAt (0)
2+
const CH_0 = '0'.charCodeAt (0)
3+
const CH_9 = '9'.charCodeAt (0)
4+
5+
module.exports = class {
6+
7+
raise (s, o) {
8+
9+
const err = Error (s)
10+
11+
for (const k in o) err [k] = o [k]
12+
13+
throw err
14+
15+
}
16+
17+
verify (str) {
18+
19+
const type = typeof str; if (type !== 'string') this.raise (`CadNum must be of type string`, {str, type})
20+
21+
const {length} = str; if (length < 14) this.raise (`CadNum must be at least 14 charaters long`, {str, length})
22+
23+
const lastColonIndex = str.lastIndexOf (':')
24+
25+
switch (lastColonIndex) {
26+
27+
case -1:
28+
this.raise (`Invalid CadNum "${str}": colon not found`, {str, lastColonIndex})
29+
30+
case 12:
31+
case 13:
32+
break
33+
34+
default:
35+
this.raise (`Invalid CadNum "${str}": the last colon found at position ${lastColonIndex}`, {str, lastColonIndex})
36+
37+
}
38+
39+
for (let index = 0; index < length; index ++) if (index !== lastColonIndex) {
40+
41+
const c = str.charCodeAt (index)
42+
43+
switch (index) {
44+
45+
case 2:
46+
case 5:
47+
if (c !== CH_COLON) this.raise (`Invalid CadNum "${str}": not a colon at position ${index}`, {str, index})
48+
break
49+
50+
default:
51+
if (c < CH_0 || c > CH_9) this.raise (`Invalid CadNum "${str}": not a digit at position ${index}`, {str, index})
52+
53+
}
54+
55+
}
56+
57+
}
58+
59+
random (options = {}) {
60+
61+
let {pre, length} = options
62+
63+
if (!pre) pre = ''
64+
65+
if (pre.length === 12 || pre.length === 13) if (pre.charCodeAt (pre.length - 1) !== CH_COLON) pre += ':'
66+
67+
if (!length) length = 14 + Math.floor (5 * Math.random ())
68+
69+
if (length <= pre.length) length = pre.length + 1
70+
71+
const b = Buffer.alloc (length)
72+
73+
for (let i = 0; i < pre.length; i ++) b [i] = pre.charCodeAt (i)
74+
75+
for (let i = pre.length; i < length; i ++) b [i] = 48 + Math.floor (10 * Math.random ())
76+
77+
b [2] = CH_COLON
78+
b [5] = CH_COLON
79+
80+
if (b.lastIndexOf (CH_COLON) < 12) {
81+
82+
let lastColonIndex = 12
83+
84+
if (length > 14 && Math.random () > 0.5) lastColonIndex ++
85+
86+
b [lastColonIndex] = CH_COLON
87+
88+
}
89+
90+
return b.toString ()
91+
92+
}
93+
94+
}

0 commit comments

Comments
 (0)