77 lines
3.3 KiB
JavaScript
77 lines
3.3 KiB
JavaScript
const { test } = require('node:test')
|
||
const assert = require('node:assert/strict')
|
||
const fs = require('node:fs')
|
||
const path = require('node:path')
|
||
const vm = require('node:vm')
|
||
const { createRequire } = require('node:module')
|
||
const esbuild = createRequire(require.resolve('vite'))('esbuild')
|
||
const moduleForTest = { exports: {} }
|
||
vm.runInNewContext(
|
||
esbuild.transformSync(fs.readFileSync(path.join(__dirname, '../src/utils/idCard.ts'), 'utf8'), {
|
||
loader: 'ts',
|
||
format: 'cjs'
|
||
}).code,
|
||
{ module: moduleForTest, exports: moduleForTest.exports }
|
||
)
|
||
const { parseIdCard, normalizeIdCard, fillIdentityFromIdCard } = moduleForTest.exports
|
||
|
||
test('accepts a valid 18-digit ID ending in X; regression for the old 20-digit regexp', () => {
|
||
const result = parseIdCard('11010519491231002X')
|
||
assert.equal(result.valid, true)
|
||
assert.equal(result.birthDate, '1949-12-31')
|
||
assert.equal(result.gender, 2)
|
||
})
|
||
test('normalizes lowercase x, full-width digits and copied whitespace', () => {
|
||
const pasted = '\uFEFF 110105\u00A019491231\u200B002x\t\n'
|
||
assert.equal(normalizeIdCard(pasted), '11010519491231002X')
|
||
assert.equal(parseIdCard(pasted).valid, true)
|
||
})
|
||
test('decodes valid leap-day birthdays and both male and female numeric check digits', () => {
|
||
const male = parseIdCard('110105196402290013')
|
||
const female = parseIdCard('110105196402290021')
|
||
assert.equal(male.valid, true)
|
||
assert.equal(male.birthDate, '1964-02-29')
|
||
assert.equal(male.gender, 1)
|
||
assert.equal(female.valid, true)
|
||
assert.equal(female.gender, 2)
|
||
})
|
||
test('rejects non-leap Feb 29, Feb 30 and the non-leap century 1900 despite valid checksums', () => {
|
||
for (const value of ['110105196302290016', '110105196402300015', '110105190002290017']) {
|
||
const result = parseIdCard(value)
|
||
assert.equal(result.valid, false)
|
||
assert.match(result.error, /出生日期/)
|
||
}
|
||
})
|
||
test('rejects incorrect checksums and wrong lengths', () => {
|
||
assert.match(parseIdCard('110105194912310020').error, /校验位/)
|
||
for (const value of ['11010519491231002', '11010519491231002XXX', 'abcdefgh1949123100X']) {
|
||
assert.equal(parseIdCard(value).valid, false)
|
||
}
|
||
})
|
||
test('autofills date and gender on valid input without inventing names or ethnicity', () => {
|
||
const form = { realName: '人工填写姓名', ethnicity: '人工选择民族', gender: 3 }
|
||
fillIdentityFromIdCard(form, '11010519491231002x')
|
||
assert.equal(form.idCard, '11010519491231002X')
|
||
assert.equal(form.birthDate, '1949-12-31')
|
||
assert.equal(form.gender, 2)
|
||
assert.equal(form.realName, '人工填写姓名')
|
||
assert.equal(form.ethnicity, '人工选择民族')
|
||
})
|
||
test('invalid partial input cannot overwrite corrected date or gender', () => {
|
||
const form = { birthDate: '1963-06-05', gender: 2 }
|
||
assert.equal(fillIdentityFromIdCard(form, '110105').valid, false)
|
||
assert.equal(form.birthDate, '1963-06-05')
|
||
assert.equal(form.gender, 2)
|
||
})
|
||
|
||
test('loading an old record fills missing defaults but preserves manual corrections', () => {
|
||
const form = { birthDate: '1963-06-05', gender: 1 }
|
||
fillIdentityFromIdCard(form, '11010519491231002X', true)
|
||
assert.equal(form.birthDate, '1963-06-05')
|
||
assert.equal(form.gender, 1)
|
||
const incomplete = { gender: 3 }
|
||
fillIdentityFromIdCard(incomplete, '11010519491231002X', true)
|
||
assert.equal(incomplete.birthDate, '1949-12-31')
|
||
assert.equal(incomplete.gender, 2)
|
||
})
|