Fixed new Date => new Date(Date.UTC(....))

Improved test
Dependency clean up
This commit is contained in:
Luca Vandro 2019-03-28 20:02:17 +01:00
parent 5eb6f3c3c8
commit 6db085e308
25 changed files with 14852 additions and 15743 deletions

8
.babelrc Normal file
View File

@ -0,0 +1,8 @@
{
"presets": [
["@babel/preset-env", {
"debug": true,
"modules": "cjs"
}]
]
}

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
[*]
indent_style = space
[*.{.json,js}]
indent_size = 2
[*.ts]
indent_size = 4

19
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/jest/bin/jest.js",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"port": 9229
}
]
}

View File

@ -1,28 +0,0 @@
{
"name": "codice-fiscale-js",
"description": "Calcolo del codice fiscale",
"main": "dist/codice.fiscale.js",
"authors": [
"Luca Vandro",
"Walter Barbagallo"
],
"license": "MIT",
"keywords": [
"codice",
"fiscale",
"italian",
"social",
"security",
"number"
],
"homepage": "https://github.com/lucavandro/CodiceFiscaleJS",
"moduleType": [],
"ignore": [
"**/.*",
"lib",
"node_modules",
"bower_components",
"test",
"tests"
]
}

840
bundle.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,9 +18,6 @@
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Codice Fiscale JS</a>
</nav>
<div class="jumbotron jumbotron-fluid text-center">
<div class="container">
<h1 class="display-4 text-success">Codice Fiscale JS</h1>

289
lib/codice-fiscale.js Normal file
View File

@ -0,0 +1,289 @@
"use strict";
var _comune = require("./comune");
var _constants = require("./constants");
var _utils = require("./utils");
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var CodiceFiscale =
/*#__PURE__*/
function () {
_createClass(CodiceFiscale, [{
key: "day",
get: function get() {
return this.birthday.getDate();
},
set: function set(d) {
this.birthday.setDate(d);
}
}, {
key: "month",
get: function get() {
return this.birthday.getMonth() + 1;
},
set: function set(m) {
this.birthday.setMonth(m - 1);
}
}, {
key: "year",
get: function get() {
return this.birthday.getFullYear();
},
set: function set(y) {
this.birthday.setFullYear(y);
}
}, {
key: "cf",
get: function get() {
return this.code;
}
}, {
key: "nameCode",
get: function get() {
return this.code.substr(3, 3);
}
}, {
key: "surnameCode",
get: function get() {
return this.code.substr(0, 3);
}
}, {
key: "checkCode",
get: function get() {
return this.code.substr(15, 1);
}
}]);
function CodiceFiscale(data) {
_classCallCheck(this, CodiceFiscale);
if (typeof data === 'string') {
if (CodiceFiscale.check(data)) {
this.code = data;
this.reverse();
} else {
throw new Error('Provided input is not a valid Codice Fiscale');
}
} else if (_typeof(data) === 'object') {
var cfData = data;
this.name = cfData.name;
this.surname = cfData.surname;
this.gender = this.checkGender(cfData.gender);
this.birthday = cfData.birthday ? (0, _utils.getValidDate)(cfData.birthday) : (0, _utils.getValidDate)(cfData.day, cfData.month, cfData.year);
this.birthplace = new _comune.Comune(cfData.birthplace, cfData.birthplaceProvincia);
this.compute();
} else {
throw new Error('Comune constructor accept either a string or a plain object. Check the documentation');
}
}
_createClass(CodiceFiscale, [{
key: "toString",
value: function toString() {
return this.code;
}
}, {
key: "toJSON",
value: function toJSON() {
return {
name: this.name,
surname: this.surname,
gender: this.gender,
birthday: this.birthday.getFullYear() + '-' + ('00' + this.birthday.getMonth()).slice(-2) + '-' + ('00' + this.birthday.getDate()).slice(-2),
birthplace: this.birthplace.nome,
birthplaceProvincia: this.birthplace.prov,
cf: this.code
};
}
}, {
key: "isValid",
value: function isValid() {
if (typeof this.code !== 'string') {
return false;
}
this.code = this.code.toUpperCase();
if (this.code.length !== 16) {
return false;
}
var expectedCheckCode = this.code.charAt(15);
var cf = this.code.slice(0, 15);
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
}
}, {
key: "omocodie",
value: function omocodie() {
var results = [];
var lastOmocode = this.code = this.code.slice(0, 15);
for (var i = this.code.length - 1; i >= 0; i = i - 1) {
var char = this.code[i];
if (char.match(/\d/) !== null) {
lastOmocode = "".concat(lastOmocode.substr(0, i)).concat(_constants.OMOCODIA_TABLE[char]).concat(lastOmocode.substr(i + 1));
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode));
}
}
return results;
}
}, {
key: "compute",
value: function compute() {
var code = this.getSurnameCode();
code += this.getNameCode();
code += this.dateCode();
code += this.birthplace.cc;
code += CodiceFiscale.getCheckCode(code);
this.code = code;
}
}, {
key: "reverse",
value: function reverse() {
this.name = this.code.substr(3, 3);
this.surname = this.code.substr(0, 3);
var yearCode = this.code.substr(6, 2);
var year19XX = parseInt("19".concat(yearCode), 10);
var year20XX = parseInt("20".concat(yearCode), 10);
var currentYear20XX = new Date().getFullYear();
var year = year20XX > currentYear20XX ? year19XX : year20XX;
var monthChar = this.code.substr(8, 1);
var month = _constants.MONTH_CODES.indexOf(monthChar);
this.gender = 'M';
var day = parseInt(this.code.substr(9, 2), 10);
if (day > 31) {
this.gender = 'F';
day = day - 40;
}
this.birthday = new Date(Date.UTC(year, month, day, 0, 0, 0, 0));
var cc = this.code.substr(11, 4);
this.birthplace = _comune.Comune.GetByCC(cc);
return this.toJSON();
}
}, {
key: "checkGender",
value: function checkGender(gender) {
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase();
if (typeof this.gender !== 'string') {
throw new Error('Gender must be a string');
}
if (this.gender !== 'M' && this.gender !== 'F') {
throw new Error('Gender must be either \'M\' or \'F\'');
}
return gender;
}
}, {
key: "getSurnameCode",
value: function getSurnameCode() {
var codeSurname = "".concat((0, _utils.extractConsonants)(this.surname)).concat((0, _utils.extractVowels)(this.surname), "XXX");
return codeSurname.substr(0, 3).toUpperCase();
}
}, {
key: "getNameCode",
value: function getNameCode() {
var codNome = (0, _utils.extractConsonants)(this.name);
if (codNome.length >= 4) {
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3);
} else {
codNome += "".concat((0, _utils.extractVowels)(this.name), "XXX");
codNome = codNome.substr(0, 3);
}
return codNome.toUpperCase();
}
}, {
key: "dateCode",
value: function dateCode() {
var year = "0".concat(this.birthday.getFullYear());
year = year.substr(year.length - 2, 2);
var month = _constants.MONTH_CODES[this.birthday.getMonth()];
var day = this.birthday.getDate();
if (this.gender.toUpperCase() === 'F') {
day += 40;
}
var dayStr = "0".concat(day);
dayStr = dayStr.substr(dayStr.length - 2, 2);
return String(year + month + dayStr);
}
}], [{
key: "getCheckCode",
value: function getCheckCode(codiceFiscale) {
var val = 0;
for (var i = 0; i < 15; i = i + 1) {
var c = codiceFiscale[i];
val += i % 2 !== 0 ? _constants.CHECK_CODE_EVEN[c] : _constants.CHECK_CODE_ODD[c];
}
val = val % 26;
return _constants.CHECK_CODE_CHARS.charAt(val);
}
}, {
key: "findLocationCode",
value: function findLocationCode(name, prov) {
return new _comune.Comune(name, prov).cc;
}
}, {
key: "computeInverse",
value: function computeInverse(codiceFiscale) {
return new CodiceFiscale(codiceFiscale).toJSON();
}
}, {
key: "compute",
value: function compute(obj) {
return new CodiceFiscale(obj).toString();
}
}, {
key: "check",
value: function check(codiceFiscale) {
if (typeof codiceFiscale !== 'string') {
return false;
}
var cf = codiceFiscale.toUpperCase();
if (cf.length !== 16) {
return false;
}
var expectedCheckCode = codiceFiscale.charAt(15);
cf = codiceFiscale.slice(0, 15);
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
}
}, {
key: "getOmocodie",
value: function getOmocodie(cf) {
return new CodiceFiscale(cf).omocodie();
}
}]);
return CodiceFiscale;
}();
CodiceFiscale.utils = {
birthplaceFields: _utils.birthplaceFields
};
module.exports = CodiceFiscale;

205
lib/comune.js Normal file
View File

@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Comune = void 0;
var _geoData = require("./geo-data");
var _utils = require("./utils");
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Comune =
/*#__PURE__*/
function () {
_createClass(Comune, [{
key: "nomeNorm",
get: function get() {
return (0, _utils.normalizeString)(this.nome);
}
}]);
function Comune(nome, prov, cc) {
var check = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
_classCallCheck(this, Comune);
if (check || cc === undefined || prov === undefined) {
var comune;
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome);
if (comune === undefined && nome.length === 4) {
comune = this.searchByCC(nome);
}
if (comune === undefined) {
throw new Error("Comune with name ".concat(nome, " doesn't exist"));
} else if (cc !== undefined && comune.cc !== cc) {
throw new Error("Comune with cc ".concat(cc, " doesn't exist"));
} else {
this.nome = comune.nome;
this.prov = comune.prov;
this.cc = comune.cc;
}
} else {
this.nome = nome;
this.prov = prov;
this.cc = cc;
}
}
_createClass(Comune, [{
key: "searchByCC",
value: function searchByCC(cc) {
var result;
try {
result = Comune.GetByCC(cc);
} catch (e) {}
if (result !== undefined) {
return result.toJSON();
}
}
}, {
key: "searchByName",
value: function searchByName(nome) {
var query = (0, _utils.normalizeString)(nome);
var left = 0;
var right = _geoData.COMUNI.length - 1;
var result = [];
while (left <= right) {
var middle = Math.floor((left + right) / 2);
var currentItem = _geoData.COMUNI[middle];
if (query === currentItem[2]) {
result.push(currentItem);
if (middle > 0 && _geoData.COMUNI[middle - 1][2] === query) {
result.push(_geoData.COMUNI[middle - 1]);
} else if (middle < _geoData.COMUNI.length - 1 && _geoData.COMUNI[middle + 1][2] === query) {
result.push(_geoData.COMUNI[middle + 1]);
}
break;
} else if (query < currentItem[2]) {
right = middle - 1;
} else {
left = middle + 1;
}
}
if (result.length === 1) {
return {
cc: result[0][0],
prov: result[0][1],
nome: result[0][2]
};
} else if (result.length > 1) {
throw new Error("Comune with name of ".concat(nome, " is found in more than one province. Please specify the province code"));
}
}
}, {
key: "searchByNameAndProvince",
value: function searchByNameAndProvince(nome, prov) {
var query = (0, _utils.normalizeString)(nome);
var left = 0;
var right = _geoData.COMUNI.length - 1;
var result;
while (left <= right) {
var middle = Math.floor((left + right) / 2);
var currentItem = _geoData.COMUNI[middle];
if (query === currentItem[2]) {
if (prov === currentItem[1]) {
result = currentItem;
} else if (middle > 0 && _geoData.COMUNI[middle - 1][2] === query && prov === _geoData.COMUNI[middle - 1][1]) {
result = _geoData.COMUNI[middle - 1];
} else if (middle < _geoData.COMUNI.length - 1 && _geoData.COMUNI[middle + 1][2] === query && prov === _geoData.COMUNI[middle + 1][1]) {
result = _geoData.COMUNI[middle + 1];
}
break;
} else if (query < currentItem[2]) {
right = middle - 1;
} else {
left = middle + 1;
}
}
if (result !== undefined) {
return {
cc: result[0],
prov: result[1],
nome: result[2]
};
} else {
throw new Error("Comune with name of ".concat(nome, " and prov ").concat(prov, " doesn't exists"));
}
}
}, {
key: "toJSON",
value: function toJSON() {
return {
cc: this.cc,
nome: this.nome,
prov: this.prov
};
}
}], [{
key: "GetByName",
value: function GetByName(name, prov) {
return new Comune(name, prov);
}
}, {
key: "GetByCC",
value: function GetByCC(cc) {
var result;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _geoData.COMUNI[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var item = _step.value;
if (item[0] === cc) {
result = item;
break;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (result !== undefined) {
return new Comune(result[2], result[1], result[0], false);
}
throw new Error("Comune with cc ".concat(cc, " doesn't exist"));
}
}]);
return Comune;
}();
exports.Comune = Comune;

101
lib/constants.js Normal file
View File

@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CHECK_CODE_CHARS = exports.OMOCODIA_TABLE = exports.CHECK_CODE_EVEN = exports.CHECK_CODE_ODD = exports.MONTH_CODES = void 0;
var MONTH_CODES = ['A', 'B', 'C', 'D', 'E', 'H', 'L', 'M', 'P', 'R', 'S', 'T'];
exports.MONTH_CODES = MONTH_CODES;
var CHECK_CODE_ODD = {
0: 1,
1: 0,
2: 5,
3: 7,
4: 9,
5: 13,
6: 15,
7: 17,
8: 19,
9: 21,
A: 1,
B: 0,
C: 5,
D: 7,
E: 9,
F: 13,
G: 15,
H: 17,
I: 19,
J: 21,
K: 2,
L: 4,
M: 18,
N: 20,
O: 11,
P: 3,
Q: 6,
R: 8,
S: 12,
T: 14,
U: 16,
V: 10,
W: 22,
X: 25,
Y: 24,
Z: 23
};
exports.CHECK_CODE_ODD = CHECK_CODE_ODD;
var CHECK_CODE_EVEN = {
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
A: 0,
B: 1,
C: 2,
D: 3,
E: 4,
F: 5,
G: 6,
H: 7,
I: 8,
J: 9,
K: 10,
L: 11,
M: 12,
N: 13,
O: 14,
P: 15,
Q: 16,
R: 17,
S: 18,
T: 19,
U: 20,
V: 21,
W: 22,
X: 23,
Y: 24,
Z: 25
};
exports.CHECK_CODE_EVEN = CHECK_CODE_EVEN;
var OMOCODIA_TABLE = {
0: 'L',
1: 'M',
2: 'N',
3: 'P',
4: 'Q',
5: 'R',
6: 'S',
7: 'T',
8: 'U',
9: 'V'
};
exports.OMOCODIA_TABLE = OMOCODIA_TABLE;
var CHECK_CODE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
exports.CHECK_CODE_CHARS = CHECK_CODE_CHARS;

122
lib/geo-data.js Normal file

File diff suppressed because one or more lines are too long

117
lib/utils.js Normal file
View File

@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.normalizeString = normalizeString;
exports.daysInMonth = daysInMonth;
exports.isValidDate = isValidDate;
exports.getValidDate = getValidDate;
exports.extractVowels = extractVowels;
exports.extractConsonants = extractConsonants;
exports.pad = pad;
exports.birthplaceFields = birthplaceFields;
var _geoData = require("./geo-data");
function normalizeString(str) {
return str.trim().replace(new RegExp(/[àá]/g), 'a\'').replace(new RegExp(/[èé]/g), 'e\'').replace(new RegExp(/[ìí]/g), 'i\'').replace(new RegExp(/[òó]/g), 'o\'').replace(new RegExp(/[ùú]/g), 'u\'').toUpperCase();
}
function daysInMonth(m, y) {
switch (m) {
case 1:
return y % 4 === 0 && y % 100 !== 0 || y % 400 === 0 ? 29 : 28;
case 8:
case 3:
case 5:
case 10:
return 30;
default:
return 31;
}
}
function isValidDate(d, m, y) {
var month = m - 1;
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y);
}
function getValidDate(d, m, y) {
if (typeof d === 'string' && m === undefined && y === undefined) {
return new Date(d);
} else if (isValidDate(d, m, y)) {
return new Date(y, m - 1, d, 0, 0, 0, 0);
} else {
throw new Error("The date ".concat(y, "/").concat(m, "/").concat(d, " is not a valid date"));
}
}
function extractVowels(str) {
return str.replace(/[^AEIOU]/gi, '');
}
function extractConsonants(str) {
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '');
}
function pad(n) {
var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
var s = String(n);
while (s.length < size) {
s = "0".concat(s);
}
return s;
}
function birthplaceFields(provinceSelector, birthplaceSelector) {
var provinceSelect = document.querySelector(provinceSelector);
var birthplaceSelect = document.querySelector(birthplaceSelector);
var optGroupProv = document.createElement('optgroup');
var optGroupEE = document.createElement('optgroup');
optGroupEE.label = '-----------';
provinceSelect.appendChild(optGroupProv);
provinceSelect.appendChild(optGroupEE);
Object.keys(_geoData.PROVINCE).forEach(function (code, i) {
var name = _geoData.PROVINCE[code];
var option = document.createElement('option');
option.value = code;
option.textContent = name;
if (code === 'EE') {
optGroupEE.appendChild(option);
} else {
optGroupProv.appendChild(option);
}
});
provinceSelect.onchange = function (e) {
var province = provinceSelect.value;
while (birthplaceSelect.firstChild) {
birthplaceSelect.removeChild(birthplaceSelect.firstChild);
}
_geoData.COMUNI.forEach(function (comune) {
var cc = comune[0];
var nome = comune[2];
var prov = comune[1];
if (prov === province) {
var option = document.createElement('option');
option.value = cc;
option.textContent = nome.toLowerCase().replace(/\b\w/g, function (l) {
return l.toUpperCase();
});
birthplaceSelect.appendChild(option);
}
});
};
provinceSelect.selectedIndex = '0';
provinceSelect.onchange();
}

8349
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "codice-fiscale-js",
"version": "2.1.0",
"version": "2.2.0",
"description": "The Italian Tax Code Library for Javascript and Typescript",
"main": "dist/codice.fiscale.umd.js",
"repository": {
@ -11,34 +11,40 @@
"test": "tests"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-jest": "^22.0.1",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.7.0",
"eslint": "^3.0.0",
"jest": "^22.0.1",
"parallel-webpack": "^2.2.0",
"regenerator-runtime": "^0.11.1",
"request": "^2.88.0",
"standard": "^10.0.3",
"webpack": "^4.20.2"
"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"babel-jest": "^24.5.0",
"babel-loader": "^8.0.5",
"jest": "^24.5.0",
"parallel-webpack": "^2.3.0",
"standard": "^12.0.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0"
},
"scripts": {
"build": "webpack && cp ./dist/codice.fiscale.var.js ./example/",
"build": "webpack",
"clean": "rm ./example/codice.fiscale.var.js",
"pretest": "npm run build",
"test": "standard && jest",
"fix": "standard --fix"
"test": "jest --debug",
"fix": "standard --fix",
"standard": "standard"
},
"author": "Luca Vandro <lucavandro@gmail.com>",
"contributors": [
"Walter Barbagallo <brb.walter@gmail.com>",
"Marco Pesani <marco.pesani@gmail.com>"
"Marco Pesani <marco.pesani@gmail.com>",
"Arsenio Siani <arsenio.siani@gmail.com>"
],
"license": "MIT",
"standard": {
"ignore": [
"dist/"
]
},
"jest": {
"moduleDirectories": [
"node_modules",
"./src"
]
}
}

View File

@ -1,204 +1,210 @@
import { Comune } from './comune';
import { CHECK_CODE_CHARS, CHECK_CODE_EVEN, CHECK_CODE_ODD, MONTH_CODES, OMOCODIA_TABLE } from './constants';
import { extractConsonants, extractVowels, getValidDate, birthplaceFields } from './utils';
import { Comune } from './comune'
import { CHECK_CODE_CHARS, CHECK_CODE_EVEN, CHECK_CODE_ODD, MONTH_CODES, OMOCODIA_TABLE } from './constants'
import { extractConsonants, extractVowels, getValidDate, birthplaceFields } from './utils'
class CodiceFiscale {
get day() {
return this.birthday.getDate();
get day () {
return this.birthday.getDate()
}
set day (d) {
this.birthday.setDate(d)
}
get month () {
return this.birthday.getMonth() + 1
}
set month (m) {
this.birthday.setMonth(m - 1)
}
get year () {
return this.birthday.getFullYear()
}
set year (y) {
this.birthday.setFullYear(y)
}
get cf () {
return this.code
}
get nameCode () {
return this.code.substr(3, 3)
}
get surnameCode () {
return this.code.substr(0, 3)
}
get checkCode () {
return this.code.substr(15, 1)
}
constructor (data) {
if (typeof data === 'string') {
if (CodiceFiscale.check(data)) {
this.code = data
this.reverse()
} else {
throw new Error('Provided input is not a valid Codice Fiscale')
}
} else if (typeof data === 'object') {
const cfData = data
this.name = cfData.name
this.surname = cfData.surname
this.gender = this.checkGender(cfData.gender)
this.birthday = cfData.birthday ? getValidDate(cfData.birthday) : getValidDate(cfData.day, cfData.month, cfData.year)
this.birthplace = new Comune(cfData.birthplace, cfData.birthplaceProvincia)
this.compute()
} else {
throw new Error('Comune constructor accept either a valid string or a plain object. Check the documentation')
}
set day(d) {
this.birthday.setDate(d);
}
static getCheckCode (codiceFiscale) {
let val = 0
for (let i = 0; i < 15; i = i + 1) {
const c = codiceFiscale[i]
val += i % 2 !== 0 ? CHECK_CODE_EVEN[c] : CHECK_CODE_ODD[c]
}
get month() {
return this.birthday.getMonth() + 1;
val = val % 26
return CHECK_CODE_CHARS.charAt(val)
}
static findLocationCode (name, prov) {
return new Comune(name, prov).cc
}
static computeInverse (codiceFiscale) {
return new CodiceFiscale(codiceFiscale).toJSON()
}
static compute (obj) {
return new CodiceFiscale(obj).toString()
}
static check (codiceFiscale) {
if (typeof codiceFiscale !== 'string') {
return false
}
set month(m) {
this.birthday.setMonth(m - 1);
let cf = codiceFiscale.toUpperCase()
if (cf.length !== 16) {
return false
}
get year() {
return this.birthday.getFullYear();
const expectedCheckCode = codiceFiscale.charAt(15)
cf = codiceFiscale.slice(0, 15)
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode
}
static getOmocodie (cf) {
return new CodiceFiscale(cf).omocodie()
}
static surnameCode(surname){
const codeSurname = `${extractConsonants(surname)}${extractVowels(surname)}XXX`
return codeSurname.substr(0, 3).toUpperCase()
}
static nameCode(name){
let codNome = extractConsonants(name)
if (codNome.length >= 4) {
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3)
} else {
codNome += `${extractVowels(name)}XXX`
codNome = codNome.substr(0, 3)
}
set year(y) {
this.birthday.setFullYear(y);
return codNome.toUpperCase()
}
static dateCode(day, month, year, gender){
year = `0${year}`
year = year.substr(year.length - 2, 2)
month = MONTH_CODES[month-1];
if (gender.toUpperCase() === 'F') {
day += 40
}
get cf() {
return this.code;
day = `0${day}`
day = day.substr(day.length - 2, 2)
return `${year}${month}${day}`
}
toString () {
return this.code
}
toJSON () {
return {
name: this.name,
surname: this.surname,
gender: this.gender,
day : this.birthday.getDate(),
year: this.birthday.getFullYear(),
month: this.birthday.getMonth()+1,
birthday: this.birthday.getFullYear() + '-' + (('00' + this.birthday.getMonth()+1).slice(-2)) + '-' + (('00' + this.birthday.getDate()).slice(-2)),
birthplace: this.birthplace.nome,
birthplaceProvincia: this.birthplace.prov,
cf: this.code
}
get nameCode() {
return this.code.substr(3, 3);
}
isValid () {
if (typeof this.code !== 'string') {
return false
}
get surnameCode() {
return this.code.substr(0, 3);
this.code = this.code.toUpperCase()
if (this.code.length !== 16) {
return false
}
get checkCode() {
return this.code.substr(15, 1);
const expectedCheckCode = this.code.charAt(15)
const cf = this.code.slice(0, 15)
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode
}
omocodie () {
const results = []
let lastOmocode = (this.code = this.code.slice(0, 15))
for (let i = this.code.length - 1; i >= 0; i = i - 1) {
const char = this.code[i]
if (char.match(/\d/) !== null) {
lastOmocode = `${lastOmocode.substr(0, i)}${OMOCODIA_TABLE[char]}${lastOmocode.substr(i + 1)}`
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode))
}
}
constructor(data) {
if (typeof data === 'string') {
if (CodiceFiscale.check(data)) {
this.code = data;
this.reverse();
}
else {
throw new Error('Provided input is not a valid Codice Fiscale');
}
}
else if (typeof data === 'object') {
const cfData = data;
this.name = cfData.name;
this.surname = cfData.surname;
this.gender = this.checkGender(cfData.gender);
this.birthday = cfData.birthday ? getValidDate(cfData.birthday) : getValidDate(cfData.day, cfData.month, cfData.year);
this.birthplace = new Comune(cfData.birthplace, cfData.birthplaceProvincia);
this.compute();
}
else {
throw new Error('Comune constructor accept either a string or a plain object. Check the documentation');
}
return results
}
compute () {
let code = this.getSurnameCode()
code += this.getNameCode()
code += this.dateCode()
code += this.birthplace.cc
code += CodiceFiscale.getCheckCode(code)
this.code = code
}
reverse () {
this.name = this.code.substr(3, 3)
this.surname = this.code.substr(0, 3)
const yearCode = this.code.substr(6, 2)
const year19XX = parseInt(`19${yearCode}`, 10)
const year20XX = parseInt(`20${yearCode}`, 10)
const currentYear20XX = new Date().getFullYear()
const year = year20XX > currentYear20XX ? year19XX : year20XX
const monthChar = this.code.substr(8, 1)
const month = MONTH_CODES.indexOf(monthChar)
this.gender = 'M'
let day = parseInt(this.code.substr(9, 2), 10)
if (day > 31) {
this.gender = 'F'
day = day - 40
}
static getCheckCode(codiceFiscale) {
let val = 0;
for (let i = 0; i < 15; i = i + 1) {
const c = codiceFiscale[i];
val += i % 2 !== 0 ? CHECK_CODE_EVEN[c] : CHECK_CODE_ODD[c];
}
val = val % 26;
return CHECK_CODE_CHARS.charAt(val);
this.birthday = new Date(Date.UTC(year, month, day, 0, 0, 0, 0))
const cc = this.code.substr(11, 4)
this.birthplace = Comune.GetByCC(cc)
return this.toJSON()
}
checkGender (gender) {
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase()
if (typeof this.gender !== 'string') {
throw new Error('Gender must be a string')
}
static findLocationCode(name, prov) {
return new Comune(name, prov).cc;
}
static computeInverse(codiceFiscale) {
return new CodiceFiscale(codiceFiscale).toJSON();
}
static compute(obj) {
return new CodiceFiscale(obj).toString();
}
static check(codiceFiscale) {
if (typeof codiceFiscale !== 'string') {
return false;
}
let cf = codiceFiscale.toUpperCase();
if (cf.length !== 16) {
return false;
}
const expectedCheckCode = codiceFiscale.charAt(15);
cf = codiceFiscale.slice(0, 15);
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
}
static getOmocodie(cf) {
return new CodiceFiscale(cf).omocodie();
}
toString() {
return this.code;
}
toJSON() {
return {
name: this.name,
surname: this.surname,
gender: this.gender,
birthday: this.birthday.getFullYear()+"-"+(("00" + this.birthday.getMonth()).slice(-2))+"-"+(("00" + this.birthday.getDate()).slice(-2)),
birthplace: this.birthplace.nome,
birthplaceProvincia: this.birthplace.prov,
cf: this.code,
};
}
isValid() {
if (typeof this.code !== 'string') {
return false;
}
this.code = this.code.toUpperCase();
if (this.code.length !== 16) {
return false;
}
const expectedCheckCode = this.code.charAt(15);
const cf = this.code.slice(0, 15);
return CodiceFiscale.getCheckCode(cf) === expectedCheckCode;
}
omocodie() {
const results = [];
let lastOmocode = (this.code = this.code.slice(0, 15));
for (let i = this.code.length - 1; i >= 0; i = i - 1) {
const char = this.code[i];
if (char.match(/\d/) !== null) {
lastOmocode = `${lastOmocode.substr(0, i)}${OMOCODIA_TABLE[char]}${lastOmocode.substr(i + 1)}`;
results.push(lastOmocode + CodiceFiscale.getCheckCode(lastOmocode));
}
}
return results;
}
compute() {
let code = this.getSurnameCode();
code += this.getNameCode();
code += this.dateCode();
code += this.birthplace.cc;
code += CodiceFiscale.getCheckCode(code);
this.code = code;
}
reverse() {
this.name = this.code.substr(3, 3);
this.surname = this.code.substr(0, 3);
const yearCode = this.code.substr(6, 2);
const year19XX = parseInt(`19${yearCode}`, 10);
const year20XX = parseInt(`20${yearCode}`, 10);
const currentYear20XX = new Date().getFullYear();
const year = year20XX > currentYear20XX ? year19XX : year20XX;
const monthChar = this.code.substr(8, 1);
const month = MONTH_CODES.indexOf(monthChar);
this.gender = 'M';
let day = parseInt(this.code.substr(9, 2), 10);
if (day > 31) {
this.gender = 'F';
day = day - 40;
}
this.birthday = new Date(year, month, day, 0, 0, 0, 0);
const cc = this.code.substr(11, 4);
this.birthplace = Comune.GetByCC(cc);
return this.toJSON();
}
checkGender(gender) {
this.gender = gender !== undefined ? gender.toUpperCase() : this.gender.toUpperCase();
if (typeof this.gender !== 'string') {
throw new Error('Gender must be a string');
}
if (this.gender !== 'M' && this.gender !== 'F') {
throw new Error('Gender must be either \'M\' or \'F\'');
}
return gender;
}
getSurnameCode() {
const codeSurname = `${extractConsonants(this.surname)}${extractVowels(this.surname)}XXX`;
return codeSurname.substr(0, 3).toUpperCase();
}
getNameCode() {
let codNome = extractConsonants(this.name);
if (codNome.length >= 4) {
codNome = codNome.charAt(0) + codNome.charAt(2) + codNome.charAt(3);
}
else {
codNome += `${extractVowels(this.name)}XXX`;
codNome = codNome.substr(0, 3);
}
return codNome.toUpperCase();
}
dateCode() {
let year = `0${this.birthday.getFullYear()}`;
year = year.substr(year.length - 2, 2);
const month = MONTH_CODES[this.birthday.getMonth()];
let day = this.birthday.getDate();
if (this.gender.toUpperCase() === 'F') {
day += 40;
}
let dayStr = `0${day}`;
dayStr = dayStr.substr(dayStr.length - 2, 2);
return String(year + month + dayStr);
if (this.gender !== 'M' && this.gender !== 'F') {
throw new Error('Gender must be either \'M\' or \'F\'')
}
return gender
}
getSurnameCode () {
return CodiceFiscale.surnameCode(this.surname);
}
getNameCode () {
return CodiceFiscale.nameCode(this.name);
}
dateCode () {
return CodiceFiscale.dateCode(this.birthday.getDate(), this.birthday.getMonth() + 1, this.birthday.getFullYear(), this.gender);
}
}
CodiceFiscale.utils = {
birthplaceFields : birthplaceFields
birthplaceFields: birthplaceFields
}
module.exports = CodiceFiscale

View File

@ -1,134 +1,121 @@
import { COMUNI } from './geo-data';
import { normalizeString } from './utils';
import { COMUNI } from './geo-data'
import { normalizeString } from './utils'
export class Comune {
get nomeNorm() {
return normalizeString(this.nome);
}
constructor(nome, prov, cc, check = true) {
if (check || cc === undefined || prov === undefined) {
let comune;
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome);
if (comune === undefined && nome.length === 4) {
comune = this.searchByCC(nome);
}
get nomeNorm () {
return normalizeString(this.nome)
}
constructor (nome, prov, cc, check = true) {
if (check || cc === undefined || prov === undefined) {
let comune
comune = prov !== undefined ? this.searchByNameAndProvince(nome, prov) : this.searchByName(nome)
if (comune === undefined && nome.length === 4) {
comune = this.searchByCC(nome)
}
if (comune === undefined) {
throw new Error(`Comune with name ${nome} doesn't exist`);
}
else if (cc !== undefined && comune.cc !== cc) {
throw new Error(`Comune with cc ${cc} doesn't exist`);
}
else {
this.nome = comune.nome;
this.prov = comune.prov;
this.cc = comune.cc;
}
} else {
this.nome = nome;
this.prov = prov;
this.cc = cc;
}
if (comune === undefined) {
throw new Error(`Comune with name ${nome} doesn't exist`)
} else if (cc !== undefined && comune.cc !== cc) {
throw new Error(`Comune with cc ${cc} doesn't exist`)
} else {
this.nome = comune.nome
this.prov = comune.prov
this.cc = comune.cc
}
} else {
this.nome = nome
this.prov = prov
this.cc = cc
}
static GetByName(name, prov) {
return new Comune(name, prov);
}
static GetByName (name, prov) {
return new Comune(name, prov)
}
static GetByCC (cc) {
let result
for (const item of COMUNI) {
if (item[0] === cc) {
result = item
break
}
}
static GetByCC(cc) {
let result;
for (const item of COMUNI) {
if (item[0] === cc) {
result = item;
break;
}
}
if (result !== undefined) {
return new Comune(result[2], result[1], result[0], false);
}
throw new Error(`Comune with cc ${cc} doesn't exist`);
if (result !== undefined) {
return new Comune(result[2], result[1], result[0], false)
}
throw new Error(`Comune with cc ${cc} doesn't exist`)
}
searchByCC(cc) {
let result;
try{
result = Comune.GetByCC(cc);
}catch(e){}
if (result !== undefined) {
return result.toJSON();
}
searchByCC (cc) {
let result
try {
result = Comune.GetByCC(cc)
} catch (e) { }
if (result !== undefined) {
return result.toJSON()
}
searchByName(nome) {
const query = normalizeString(nome);
let left = 0;
let right = COMUNI.length - 1;
const result = [];
while (left <= right) {
const middle = Math.floor((left + right) / 2);
const currentItem = COMUNI[middle];
if (query === currentItem[2]) {
result.push(currentItem);
if (middle > 0 && COMUNI[middle - 1][2] === query) {
result.push(COMUNI[middle - 1]);
}
else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query) {
result.push(COMUNI[middle + 1]);
}
break;
}
else if (query < currentItem[2]) {
right = middle - 1;
}
else {
left = middle + 1;
}
}
if (result.length === 1) {
return { cc: result[0][0], prov: result[0][1], nome: result[0][2] };
}
else if (result.length > 1) {
throw new Error(`Comune with name of ${nome} is found in more than one province. Please specify the province code`);
}
searchByName (nome) {
const query = normalizeString(nome)
let left = 0
let right = COMUNI.length - 1
const result = []
while (left <= right) {
const middle = Math.floor((left + right) / 2)
const currentItem = COMUNI[middle]
if (query === currentItem[2]) {
result.push(currentItem)
if (middle > 0 && COMUNI[middle - 1][2] === query) {
result.push(COMUNI[middle - 1])
} else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query) {
result.push(COMUNI[middle + 1])
}
break
} else if (query < currentItem[2]) {
right = middle - 1
} else {
left = middle + 1
}
}
searchByNameAndProvince(nome, prov) {
const query = normalizeString(nome);
let left = 0;
let right = COMUNI.length - 1;
let result;
while (left <= right) {
const middle = Math.floor((left + right) / 2);
const currentItem = COMUNI[middle];
if (query === currentItem[2]) {
if (prov === currentItem[1]) {
result = currentItem;
}
else if (middle > 0 && COMUNI[middle - 1][2] === query && prov === COMUNI[middle - 1][1]) {
result = COMUNI[middle - 1];
}
else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query && prov === COMUNI[middle + 1][1]) {
result = COMUNI[middle + 1];
}
break;
}
else if (query < currentItem[2]) {
right = middle - 1;
}
else {
left = middle + 1;
}
}
if (result !== undefined) {
return { cc: result[0], prov: result[1], nome: result[2] };
}
else {
throw new Error(`Comune with name of ${nome} and prov ${prov} doesn't exists`);
}
if (result.length === 1) {
return { cc: result[0][0], prov: result[0][1], nome: result[0][2] }
} else if (result.length > 1) {
throw new Error(`Comune with name of ${nome} is found in more than one province. Please specify the province code`)
}
}
searchByNameAndProvince (nome, prov) {
const query = normalizeString(nome)
let left = 0
let right = COMUNI.length - 1
let result
while (left <= right) {
const middle = Math.floor((left + right) / 2)
const currentItem = COMUNI[middle]
if (query === currentItem[2]) {
if (prov === currentItem[1]) {
result = currentItem
} else if (middle > 0 && COMUNI[middle - 1][2] === query && prov === COMUNI[middle - 1][1]) {
result = COMUNI[middle - 1]
} else if (middle < COMUNI.length - 1 && COMUNI[middle + 1][2] === query && prov === COMUNI[middle + 1][1]) {
result = COMUNI[middle + 1]
}
break
} else if (query < currentItem[2]) {
right = middle - 1
} else {
left = middle + 1
}
}
if (result !== undefined) {
return { cc: result[0], prov: result[1], nome: result[2] }
} else {
throw new Error(`Comune with name of ${nome} and prov ${prov} doesn't exists`)
}
}
toJSON(){
return {
cc : this.cc,
nome : this.nome,
prov : this.prov
}
toJSON () {
return {
cc: this.cc,
nome: this.nome,
prov: this.prov
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,91 @@
import { PROVINCE, COMUNI } from './geo-data';
import { PROVINCE, COMUNI } from './geo-data'
export function normalizeString(str) {
return str.trim()
.replace(new RegExp(/[àá]/g), 'a\'')
.replace(new RegExp(/[èé]/g), 'e\'')
.replace(new RegExp(/[ìí]/g), 'i\'')
.replace(new RegExp(/[òó]/g), 'o\'')
.replace(new RegExp(/[ùú]/g), 'u\'')
.toUpperCase();
export function normalizeString (str) {
return str.trim()
.replace(new RegExp(/[àá]/g), 'a\'')
.replace(new RegExp(/[èé]/g), 'e\'')
.replace(new RegExp(/[ìí]/g), 'i\'')
.replace(new RegExp(/[òó]/g), 'o\'')
.replace(new RegExp(/[ùú]/g), 'u\'')
.toUpperCase()
}
export function daysInMonth(m, y) {
switch (m) {
case 1:
return (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0) ? 29 : 28;
case 8:
case 3:
case 5:
case 10:
return 30;
default:
return 31;
}
export function daysInMonth (m, y) {
switch (m) {
case 1:
return (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0) ? 29 : 28
case 8:
case 3:
case 5:
case 10:
return 30
default:
return 31
}
}
export function isValidDate(d, m, y) {
const month = m - 1;
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y);
export function isValidDate (d, m, y) {
const month = m - 1
return month >= 0 && month < 12 && d > 0 && d <= daysInMonth(month, y)
}
export function getValidDate(d, m, y) {
if(typeof d === 'string' && m === undefined && y === undefined){
return new Date(d);
}else if (isValidDate(d, m, y)) {
return new Date(y, m - 1, d, 0, 0, 0, 0);
}
else {
throw new Error(`The date ${y}/${m}/${d} is not a valid date`);
}
export function getValidDate (d, m, y) {
if (typeof d === 'string' && m === undefined && y === undefined) {
return new Date(d)
} else if (isValidDate(d, m, y)) {
return new Date(y, m - 1, d, 0, 0, 0, 0)
} else {
throw new Error(`The date ${y}/${m}/${d} is not a valid date`)
}
}
export function extractVowels(str) {
return str.replace(/[^AEIOU]/gi, '');
export function extractVowels (str) {
return str.replace(/[^AEIOU]/gi, '')
}
export function extractConsonants(str) {
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '');
export function extractConsonants (str) {
return str.replace(/[^BCDFGHJKLMNPQRSTVWXYZ]/gi, '')
}
export function pad(n, size = 2) {
let s = String(n);
while (s.length < size) {
s = `0${s}`;
}
return s;
export function pad (n, size = 2) {
let s = String(n)
while (s.length < size) {
s = `0${s}`
}
return s
}
export function birthplaceFields(provinceSelector, birthplaceSelector) {
const provinceSelect = document.querySelector(provinceSelector);
const birthplaceSelect = document.querySelector(birthplaceSelector);
const optGroupProv = document.createElement('optgroup');
const optGroupEE = document.createElement('optgroup');
optGroupEE.label = "-----------";
provinceSelect.appendChild(optGroupProv);
provinceSelect.appendChild(optGroupEE);
Object.keys(PROVINCE).forEach((code, i) => {
const name = PROVINCE[code];
const option = document.createElement('option');
option.value = code;
option.textContent = name;
if(code === 'EE'){
optGroupEE.appendChild(option);
} else {
optGroupProv.appendChild(option);
}
});
provinceSelect.onchange = (e)=>{
let province = provinceSelect.value;
while (birthplaceSelect.firstChild) {
birthplaceSelect.removeChild(birthplaceSelect.firstChild);
}
COMUNI.forEach((comune)=>{
let cc = comune[0], nome = comune[2], prov = comune[1];
if(prov === province){
let option = document.createElement('option');
option.value = cc;
option.textContent = nome.toLowerCase().replace(/\b\w/g, l => l.toUpperCase());
birthplaceSelect.appendChild(option);
}
});
export function birthplaceFields (provinceSelector, birthplaceSelector) {
const provinceSelect = document.querySelector(provinceSelector)
const birthplaceSelect = document.querySelector(birthplaceSelector)
const optGroupProv = document.createElement('optgroup')
const optGroupEE = document.createElement('optgroup')
optGroupEE.label = '-----------'
provinceSelect.appendChild(optGroupProv)
provinceSelect.appendChild(optGroupEE)
Object.keys(PROVINCE).forEach((code, i) => {
const name = PROVINCE[code]
const option = document.createElement('option')
option.value = code
option.textContent = name
if (code === 'EE') {
optGroupEE.appendChild(option)
} else {
optGroupProv.appendChild(option)
}
})
provinceSelect.selectedIndex = "0";
provinceSelect.onchange();
}
provinceSelect.onchange = (e) => {
let province = provinceSelect.value
while (birthplaceSelect.firstChild) {
birthplaceSelect.removeChild(birthplaceSelect.firstChild)
}
COMUNI.forEach((comune) => {
let cc = comune[0]
let nome = comune[2]
let prov = comune[1]
if (prov === province) {
let option = document.createElement('option')
option.value = cc
option.textContent = nome.toLowerCase().replace(/\b\w/g, l => l.toUpperCase())
birthplaceSelect.appendChild(option)
}
})
}
provinceSelect.selectedIndex = '0'
provinceSelect.onchange()
}

View File

@ -1,15 +1,17 @@
import CodiceFiscale from '../src/index'
import CodiceFiscale from '../src/codice-fiscale.js';
import { exists } from 'fs';
let { describe, test, expect } = global
describe('Codice Fiscale', () => {
test('esiste un oggetto chiamato CodiceFiscale', () => {
expect(CodiceFiscale).not.toBe(undefined)
expect(CodiceFiscale).toBeDefined()
})
})
describe('CodiceFiscale.surnameCode', () => {
test('è definito', () => {
expect(CodiceFiscale.surnameCode).not.toBe(undefined)
expect(CodiceFiscale.surnameCode).toBeDefined()
})
test('restituisce il corretto risultato in caso di sufficienti consonanti', () => {
@ -23,7 +25,7 @@ describe('CodiceFiscale.surnameCode', () => {
describe('CodiceFiscale.nameCode', () => {
test('è definito', () => {
expect(CodiceFiscale.nameCode).not.toBe(undefined)
expect(CodiceFiscale.nameCode).toBeDefined()
})
test('restituisce il corretto risultato in caso di sufficienti consonanti', () => {
@ -37,7 +39,7 @@ describe('CodiceFiscale.nameCode', () => {
describe('CodiceFiscale.dateCode', () => {
test('è definito', () => {
expect(CodiceFiscale.dateCode).not.toBe(undefined)
expect(CodiceFiscale.dateCode).toBeDefined()
})
test('restituisce il corretto risultato', () => {
@ -47,7 +49,7 @@ describe('CodiceFiscale.dateCode', () => {
describe('CodiceFiscale.getCheckCode', () => {
test('è definito', () => {
expect(CodiceFiscale.getCheckCode).not.toBe(undefined)
expect(CodiceFiscale.getCheckCode).toBeDefined()
})
test('restituisce il corretto risultato', () => {
@ -57,7 +59,7 @@ describe('CodiceFiscale.getCheckCode', () => {
describe('CodiceFiscale.compute', () => {
test('è definito', () => {
expect(CodiceFiscale.compute).not.toBe(undefined)
expect(CodiceFiscale.compute).toBeDefined()
})
test('calcola il codice fiscale', () => {
@ -101,13 +103,13 @@ describe('CodiceFiscale.compute', () => {
birthplaceProvincia: 'EE'
})
}
expect(comuneInventato).toThrowError('Location not found')
expect(comuneInventato).toThrowError('Comune with name of Foo and prov EE doesn\'t exists')
})
})
describe('CodiceFiscale.findLocationCode', () => {
test('è definito', () => {
expect(CodiceFiscale.findLocationCode).not.toBe(undefined)
expect(CodiceFiscale.findLocationCode).toBeDefined()
})
test('trova il codice del comune', () => {
@ -126,20 +128,20 @@ describe('CodiceFiscale.findLocationCode', () => {
var comuneInventato = function () {
CodiceFiscale.findLocationCode('Foo', 'Bar')
}
expect(comuneInventato).toThrowError('Area code not found')
expect(comuneInventato).toThrowError('Comune with name of Foo and prov Bar doesn\'t exists')
})
test('se il comune non esiste lancia un eccezione', () => {
var comuneInventato = function () {
CodiceFiscale.findLocationCode('Foo', 'RM')
}
expect(comuneInventato).toThrowError('Location not found')
expect(comuneInventato).toThrowError('Comune with name of Foo and prov RM doesn\'t exists')
})
})
describe('CodiceFiscale.check', () => {
test('è definito', () => {
expect(CodiceFiscale.check).not.toBe(undefined)
expect(CodiceFiscale.check).toBeDefined()
})
test('controlla se il codice fiscale è valido', () => {
@ -166,7 +168,7 @@ describe('CodiceFiscale.check', () => {
describe('CodiceFiscale.getOmocodie', () => {
test('è definito', () => {
expect(CodiceFiscale.getOmocodie).not.toBe(undefined)
expect(CodiceFiscale.getOmocodie).toBeDefined()
})
test('calcola le omocodie dato un codice fiscale', () => {
@ -177,36 +179,62 @@ describe('CodiceFiscale.getOmocodie', () => {
describe('Calcolo codice fiscale inverso -> metodo .computeInverse', () => {
test('è definito', () => {
expect(CodiceFiscale.computeInverse).not.toBe(undefined)
expect(CodiceFiscale.computeInverse).toBeDefined()
})
test("se l'input non è una stringa lancia un eccezione", () => {
var notAString = function () {
CodiceFiscale.computeInverse(0)
}
expect(notAString).toThrowError('Provided input is not a valid Codice Fiscale')
expect(notAString).toThrowError("Comune constructor accept either a valid string or a plain object. Check the documentation")
})
test("restituisce falso se l'input è stringa formattata male", () => {
var notValid = function () {
CodiceFiscale.computeInverse('BNZVCN32SC0E573Z')
}
expect(notValid).toThrowError('Provided input is not a valid Codice Fiscale')
expect(notValid).toThrowError("Provided input is not a valid Codice Fiscale")
})
/* Nome: MARIO
* Cognome: ROSSI
* Nato a : ROMA (RM)
* Giorno : 23
* Mese : Giugno (6)
* Anno : 1980
* Sesso : M
*/
let mario_rossi_cf = "RSSMRA80H23H501T";
test('restituisce il genere corretto', () => {
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').gender).toEqual('M')
expect(CodiceFiscale.computeInverse(mario_rossi_cf).gender).toEqual('M')
})
test('restituisce la città natale corretta', () => {
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').birthplace).toEqual('ROMA')
expect(CodiceFiscale.computeInverse(mario_rossi_cf).birthplace).toEqual('ROMA')
})
test('restituisce la provincia della città natale corretta', () => {
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').birthplaceProvincia).toEqual('RM')
expect(CodiceFiscale.computeInverse(mario_rossi_cf).birthplaceProvincia).toEqual('RM')
})
test('restituisce il giorno di nascita come numero compreso tra 1 e 31', () => {
expect(CodiceFiscale.computeInverse('MRNLCU00A01H501J').day >= 1 && CodiceFiscale.computeInverse('MRNLCU00A01H501J').day <= 31).toBe(true)
let day = CodiceFiscale.computeInverse(mario_rossi_cf).day
expect(day >= 1 && day <= 31).toBe(true)
})
test('restituisce il giorno corretto', () => {
expect(CodiceFiscale.computeInverse(mario_rossi_cf).day).toBe(23)
})
test('restituisce il mese corretto', () => {
expect(CodiceFiscale.computeInverse(mario_rossi_cf).month).toBe(6);
})
test('restituisce anno corretto', () => {
expect(CodiceFiscale.computeInverse(mario_rossi_cf).year).toBe(1980);
})
})

View File

@ -4,6 +4,7 @@ const createVariants = require('parallel-webpack').createVariants
function createConfig (options) {
return {
mode: "production",
entry: {
'codice.fiscale': './src/codice-fiscale.js'
},
@ -22,19 +23,14 @@ function createConfig (options) {
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['babel-preset-env']
}
loader: 'babel-loader'
}
}
]
},
plugins: [
new webpack
.optimize
.UglifyJsPlugin()
]
optimization: {
minimize: true
}
}
}

2484
yarn.lock

File diff suppressed because it is too large Load Diff