Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/placa renavam #138

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ describe('Public API', () => {
'capitalize',
'formatCurrency',
'parseCurrency',
'isValidRenavam',
'isValidPlate',
];

Object.keys(API).forEach((method) => {
Expand Down
2 changes: 2 additions & 0 deletions src/utilities/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { isValid as isValidIE } from './inscricao-estadual';
export { isValid as isValidPlate } from './plate';
export { isValid as isValidRenavam } from './renavam';
export { isValid as isValidPIS } from './pis';
export { isValid as isValidPhone, isValidMobilePhone, isValidLandlinePhone } from './phone';
export { isValid as isValidEmail } from './email';
Expand Down
84 changes: 84 additions & 0 deletions src/utilities/plate/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { isValid } from '.';

describe('isValid', () => {
describe('should return false', () => {
test('when is a empty string', () => {
expect(isValid('')).toBe(false);
});

test('when is null', () => {
expect(isValid(null as any)).toBe(false);
});

test('when is undefined', () => {
expect(isValid(undefined as any)).toBe(false);
});

test('when is a boolean', () => {
expect(isValid(true as any)).toBe(false);
expect(isValid(false as any)).toBe(false);
});

test('when is a object', () => {
expect(isValid({} as any)).toBe(false);
});

test('when is a array', () => {
expect(isValid([] as any)).toBe(false);
});

test(`when dont match with CPF length`, () => {
expect(isValid('IWH-86288')).toBe(false);
});

test('when contains only letters', () => {
expect(isValid('IWH')).toBe(false);
});

test('when contains only numbers', () => {
expect(isValid('8628')).toBe(false);
});

test('when is invalid mercosul plate', () => {
expect(isValid('IWH-8628', { mercosul: true })).toBe(false);
});

test('when is invalid motorcycle mercosul plate', () => {
expect(isValid('AAA-1A11', { mercosul: true, motorcycle: true })).toBe(false);
});

test('when options params is not pass in mercosul plate', () => {
expect(isValid('AAA-1A11')).toBe(false);
});

test('when options params is not pass in motorcycle mercosul plate', () => {
expect(isValid('AAA-11A1', { mercosul: true })).toBe(false);
});
});

describe('should return true', () => {
test('when is a valid plate without mask', () => {
expect(isValid('IWH8628')).toBe(true);
});

test('when is a valid plate with mask', () => {
expect(isValid('IWH-8628')).toBe(true);
});

test('when is a valid mercosul plate', () => {
expect(isValid('AAA-1A11', { mercosul: true })).toBe(true);
});

test('when is a valid motorcycle mercosul plate', () => {
expect(isValid('AAA-11A1', { mercosul: true, motorcycle: true })).toBe(true);
});

test('when is a valid mercosul plate without mask', () => {
expect(isValid('AAA1A11', { mercosul: true })).toBe(true);
});

test('when is a valid motorcycle mercosul plate without mask', () => {
expect(isValid('AAA11A1', { mercosul: true, motorcycle: true })).toBe(true);
});
});
});
18 changes: 18 additions & 0 deletions src/utilities/plate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export type Options = {
mercosul?: boolean;
motorcycle?: boolean;
};

export function isValid(input: string, options?: Options) {
if (!input || typeof input !== 'string') return false;

const plate = input.replace('-', '');

if (options?.mercosul && options?.motorcycle) {
return /^[a-zA-Z]{3}[0-9]{2}[a-zA-Z]{1}[0-9]{1}$/.test(plate);
} else if (options?.mercosul) {
return /^[a-zA-Z]{3}[0-9]{1}[a-zA-Z]{1}[0-9]{2}$/.test(plate);
} else {
return /^[a-zA-Z]{3}[0-9]{4}$/.test(plate);
}
}
56 changes: 56 additions & 0 deletions src/utilities/renavam/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { isValid, LENGTH } from '.';

describe('isValid', () => {
describe('should return false', () => {
test('when is a empty string', () => {
expect(isValid('')).toBe(false);
});

test('when is null', () => {
expect(isValid(null as any)).toBe(false);
});

test('when is undefined', () => {
expect(isValid(undefined as any)).toBe(false);
});

test('when is a boolean', () => {
expect(isValid(true as any)).toBe(false);
expect(isValid(false as any)).toBe(false);
});

test('when is a object', () => {
expect(isValid({} as any)).toBe(false);
});

test('when is a array', () => {
expect(isValid([] as any)).toBe(false);
});

test(`when dont match with CPF length (${LENGTH})`, () => {
expect(isValid('123456')).toBe(false);
});

test('when contains only letters or special characters', () => {
expect(isValid('abcabcabcde')).toBe(false);
});

test('when is a invalid Renavam', () => {
expect(isValid('95965727047')).toBe(false);
});

test('when is a invalid Renavam test numbers with letters', () => {
expect(isValid('foo391.838.38test0-66')).toBe(false);
});
});

describe('should return true', () => {
test('when is a Renavam valid without mask', () => {
expect(isValid('95965727048')).toBe(true);
});

test('when is a valid Renavam with mask', () => {
expect(isValid('9596572704-8')).toBe(true);
});
});
});
39 changes: 39 additions & 0 deletions src/utilities/renavam/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//base on https://github.com/eliseuborges/Renavam/blob/master/Renavam.js
import { onlyNumbers } from '../../helpers';

export const MIN_LENGTH = 9;
export const LENGTH = 11;
export const SUM = 284;

export function isValid(input: string) {
if (!input || typeof input !== 'string' || input.length < MIN_LENGTH) return false;

const numeric = onlyNumbers(input.padStart(11, '0'));

if (!numeric.match('[0-9]{11}')) return false;

const resultWithoutDigit = numeric.substring(0, 10).split('').reverse().join('');
const sum = sumCalculationRest(resultWithoutDigit);
const realDigit = parseInt(input.substring(input.length - 1, input.length));

return sum === realDigit;
}

function sumCalculationRest(input: string) {
let sum = 0;
let multiple = 2;

for (let i = 0; i < 10; i++) {
sum += parseInt(input.substring(i, i + 1)) * multiple;

if (multiple >= 9) {
multiple = 2;
} else {
multiple++;
}
}

sum = LENGTH - (sum % LENGTH);

return sum;
}