Repository: validatorjs/validator.js
Pull request #1989 (2022-06-16 16:52:07)

Update isVAT.js
Add basic regex support to all countries listed in [VAT identification number - Wikipedia](https://en.wikipedia.org/wiki/VAT_identification_number);

More extended validation for PT(Portugal).

<!--
Add a descriptive title textbox above, e.g.
feat(validatorName): brief title of what has been done
-->

<!--- briefly describe what you have done in this PR --->

## Checklist

- [ ] PR contains only changes related; no stray files, etc.
- [ ] README updated (where applicable)
- [ ] Tests written (where applicable)


codecov[bot]: # [Codecov](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) Report
> Merging [#1989](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) (b033789) into [master](https://codecov.io/gh/validatorjs/validator.js/commit/cfcf9113c69b97477c409909a8729fa8efa0d595?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) (cfcf911) will **decrease** coverage by `3.31%`.
> The diff coverage is `7.69%`.

```diff
@@             Coverage Diff             @@
##            master    #1989      +/-   ##
===========================================
- Coverage   100.00%   96.68%   -3.32%     
===========================================
  Files          103      103              
  Lines         2097     2174      +77     
  Branches       473      475       +2     
===========================================
+ Hits          2097     2102       +5     
- Misses           0       72      +72     
```


| [Impacted Files](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) | Coverage Δ | |
|---|---|---|
| [src/lib/isVAT.js](https://codecov.io/gh/validatorjs/validator.js/pull/1989/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs#diff-c3JjL2xpYi9pc1ZBVC5qcw==) | `15.29% <7.69%> (-84.71%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs). Last update [cfcf911...b033789](https://codecov.io/gh/validatorjs/validator.js/pull/1989?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).

WikiRik: Can you add new tests for these?
Dev1lDragon: @WikiRik I added some tests for all element of vat validator list
rubiin: @Dev1lDragon can you squash the commits. There seems to be more than 10+ commits

Patch:
diff --git a/README.md b/README.md
index 9674841..f4ecc2a 100644
--- a/README.md
+++ b/README.md
@@ -167,7 +167,7 @@ Validator                               | Description
 **isURL(str [, options])**              | check if the string is an URL.<br/><br/>`options` is an object which defaults to `{ protocols: ['http','https','ftp'], require_tld: true, require_protocol: false, require_host: true, require_port: false, require_valid_protocol: true, allow_underscores: false, host_whitelist: false, host_blacklist: false, allow_trailing_dot: false, allow_protocol_relative_urls: false, allow_fragments: true, allow_query_components: true, disallow_auth: false, validate_length: true }`.<br/><br/>require_protocol - if set as true isURL will return false if protocol is not present in the URL.<br/>require_valid_protocol - isURL will check if the URL's protocol is present in the protocols option.<br/>protocols - valid protocols can be modified with this option.<br/>require_host - if set as false isURL will not check if host is present in the URL.<br/>require_port - if set as true isURL will check if port is present in the URL.<br/>allow_protocol_relative_urls - if set as true protocol relative URLs will be allowed.<br/>allow_fragments - if set as false isURL will return false if fragments are present.<br/>allow_query_components - if set as false isURL will return false if query components are present.<br/>validate_length - if set as false isURL will skip string length validation (2083 characters is IE max URL length).
 **isUUID(str [, version])**             | check if the string is a UUID (version 1, 2, 3, 4 or 5).
 **isVariableWidth(str)**                | check if the string contains a mixture of full and half-width chars.
-**isVAT(str, countryCode)**                | checks that the string is a [valid VAT number](https://en.wikipedia.org/wiki/VAT_identification_number) if validation is available for the given country code matching [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). <br/><br/>Available country codes: `[ 'GB', 'IT','NL' ]`.
+**isVAT(str, countryCode)**             | checks that the string is a [valid VAT number](https://en.wikipedia.org/wiki/VAT_identification_number) if validation is available for the given country code matching [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). <br/><br/>Available country codes: `[ 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'EL', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'AL', 'MK', 'AU', 'BY', 'CA', 'IS', 'IN', 'ID', 'IL', 'KZ', 'NZ', 'NG', 'NO', 'PH', 'RU', 'SM', 'SA', 'RS', 'CH', 'TR', 'UA', 'GB', 'UZ', 'AR', 'BO', 'BR', 'CL', 'CO', 'CR', 'EC', 'SV', 'GT', 'HN', 'MX', 'NI', 'PA', 'PY', 'PE', 'DO', 'UY', 'VE' ]`.
 **isWhitelisted(str, chars)**           | checks characters if they appear in the whitelist.
 **matches(str, pattern [, modifiers])** | check if string matches the pattern.<br/><br/>Either `matches('foo', /foo/i)` or `matches('foo', 'foo', 'i')`.
 
diff --git a/src/lib/isVAT.js b/src/lib/isVAT.js
index 884b066..9559356 100644
--- a/src/lib/isVAT.js
+++ b/src/lib/isVAT.js
@@ -1,9 +1,101 @@
 import assertString from './util/assertString';
+import * as algorithms from './util/algorithms';
+
+const PT = (str) => {
+  const match = str.match(/^(PT)?(\d{9})$/);
+  if (!match) {
+    return false;
+  }
+
+  const tin = match[2];
+
+  const checksum = 11 - (algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(a => parseInt(a, 10)), 9) % 11);
+  if (checksum > 9) {
+    return parseInt(tin[8], 10) === 0;
+  }
+  return checksum === parseInt(tin[8], 10);
+};
 
 export const vatMatchers = {
-  GB: /^GB((\d{3} \d{4} ([0-8][0-9]|9[0-6]))|(\d{9} \d{3})|(((GD[0-4])|(HA[5-9]))[0-9]{2}))$/,
-  IT: /^(IT)?[0-9]{11}$/,
-  NL: /^(NL)?[0-9]{9}B[0-9]{2}$/,
+  /**
+   * European Union VAT identification numbers
+   */
+  AT: str => /^(AT)?U\d{8}$/.test(str),
+  BE: str => /^(BE)?\d{10}$/.test(str),
+  BG: str => /^(BG)?\d{9,10}$/.test(str),
+  HR: str => /^(HR)?\d{11}$/.test(str),
+  CY: str => /^(CY)?\w{9}$/.test(str),
+  CZ: str => /^(CZ)?\d{8,10}$/.test(str),
+  DK: str => /^(DK)?\d{8}$/.test(str),
+  EE: str => /^(EE)?\d{9}$/.test(str),
+  FI: str => /^(FI)?\d{8}$/.test(str),
+  FR: str => /^(FR)?\w{2}\d{9}$/.test(str),
+  DE: str => /^(DE)?\d{9}$/.test(str),
+  EL: str => /^(EL)?\d{9}$/.test(str),
+  HU: str => /^(HU)?\d{8}$/.test(str),
+  IE: str => /^(IE)?\d{7}\w{1}(W)?$/.test(str),
+  IT: str => /^(IT)?\d{11}$/.test(str),
+  LV: str => /^(LV)?\d{11}$/.test(str),
+  LT: str => /^(LT)?\d{9,12}$/.test(str),
+  LU: str => /^(LU)?\d{8}$/.test(str),
+  MT: str => /^(MT)?\d{8}$/.test(str),
+  NL: str => /^(NL)?\d{9}B\d{2}$/.test(str),
+  PL: str => /^(PL)?(\d{10}|(\d{3}-\d{3}-\d{2}-\d{2})|(\d{3}-\d{2}-\d{2}-\d{3}))$/.test(str),
+  PT,
+  RO: str => /^(RO)?\d{2,10}$/.test(str),
+  SK: str => /^(SK)?\d{10}$/.test(str),
+  SI: str => /^(SI)?\d{8}$/.test(str),
+  ES: str => /^(ES)?\w\d{7}[A-Z]$/.test(str),
+  SE: str => /^(SE)?\d{12}$/.test(str),
+
+  /**
+   * VAT numbers of non-EU countries
+   */
+  AL: str => /^(AL)?\w{9}[A-Z]$/.test(str),
+  MK: str => /^(MK)?\d{13}$/.test(str),
+  AU: str => /^(AU)?\d{11}$/.test(str),
+  BY: str => /^(УНП )?\d{9}$/.test(str),
+  CA: str => /^(CA)?\d{9}$/.test(str),
+  IS: str => /^(IS)?\d{5,6}$/.test(str),
+  IN: str => /^(IN)?\d{15}$/.test(str),
+  ID: str => /^(ID)?(\d{15}|(\d{2}.\d{3}.\d{3}.\d{1}-\d{3}.\d{3}))$/.test(str),
+  IL: str => /^(IL)?\d{9}$/.test(str),
+  KZ: str => /^(KZ)?\d{9}$/.test(str),
+  NZ: str => /^(NZ)?\d{9}$/.test(str),
+  NG: str => /^(NG)?(\d{12}|(\d{8}-\d{4}))$/.test(str),
+  NO: str => /^(NO)?\d{9}MVA$/.test(str),
+  PH: str => /^(PH)?(\d{12}|\d{3} \d{3} \d{3} \d{3})$/.test(str),
+  RU: str => /^(RU)?(\d{10}|\d{12})$/.test(str),
+  SM: str => /^(SM)?\d{5}$/.test(str),
+  SA: str => /^(SA)?\d{15}$/.test(str),
+  RS: str => /^(RS)?\d{9}$/.test(str),
+  CH: str => /^(CH)?(\d{6}|\d{9}|(\d{3}.\d{3})|(\d{3}.\d{3}.\d{3}))(TVA|MWST|IVA)$/.test(str),
+  TR: str => /^(TR)?\d{10}$/.test(str),
+  UA: str => /^(UA)?\d{12}$/.test(str),
+  GB: str => /^GB((\d{3} \d{4} ([0-8][0-9]|9[0-6]))|(\d{9} \d{3})|(((GD[0-4])|(HA[5-9]))[0-9]{2}))$/.test(str),
+  UZ: str => /^(UZ)?\d{9}$/.test(str),
+
+  /**
+   * VAT numbers of Latin American countries
+   */
+  AR: str => /^(AR)?\d{11}$/.test(str),
+  BO: str => /^(BO)?\d{7}$/.test(str),
+  BR: str => /^(BR)?((\d{2}.\d{3}.\d{3}\/\d{4}-\d{2})|(\d{3}.\d{3}.\d{3}-\d{2}))$/.test(str),
+  CL: str => /^(CL)?\d{8}-\d{1}$/.test(str),
+  CO: str => /^(CO)?\d{10}$/.test(str),
+  CR: str => /^(CR)?\d{9,12}$/.test(str),
+  EC: str => /^(EC)?\d{13}$/.test(str),
+  SV: str => /^(SV)?\d{4}-\d{6}-\d{3}-\d{1}$/.test(str),
+  GT: str => /^(GT)?\d{7}-\d{1}$/.test(str),
+  HN: str => /^(HN)?$/.test(str),
+  MX: str => /^(MX)?\w{3,4}\d{6}\w{3}$/.test(str),
+  NI: str => /^(NI)?\d{3}-\d{6}-\d{4}\w{1}$/.test(str),
+  PA: str => /^(PA)?$/.test(str),
+  PY: str => /^(PY)?\d{6,8}-\d{1}$/.test(str),
+  PE: str => /^(PE)?\d{11}$/.test(str),
+  DO: str => /^(DO)?(\d{11}|(\d{3}-\d{7}-\d{1})|[1,4,5]{1}\d{8}|([1,4,5]{1})-\d{2}-\d{5}-\d{1})$/.test(str),
+  UY: str => /^(UY)?\d{12}$/.test(str),
+  VE: str => /^(VE)?[J,G,V,E]{1}-(\d{9}|(\d{8}-\d{1}))$/.test(str),
 };
 
 export default function isVAT(str, countryCode) {
@@ -11,7 +103,7 @@ export default function isVAT(str, countryCode) {
   assertString(countryCode);
 
   if (countryCode in vatMatchers) {
-    return vatMatchers[countryCode].test(str);
+    return vatMatchers[countryCode](str);
   }
   throw new Error(`Invalid country code: '${countryCode}'`);
 }


Test patch:
diff --git a/test/validators.js b/test/validators.js
index 16fb6b8..07b3268 100644
--- a/test/validators.js
+++ b/test/validators.js
@@ -11915,6 +11915,620 @@ describe('Validators', () => {
     });
   });
   it('should validate VAT numbers', () => {
+    test({
+      validator: 'isVAT',
+      args: ['AT'],
+      valid: [
+        'ATU12345678',
+        'U12345678',
+      ],
+      invalid: [
+        'AT 12345678',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['BE'],
+      valid: [
+        'BE1234567890',
+        '1234567890',
+      ],
+      invalid: [
+        'BE 1234567890',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['BG'],
+      valid: [
+        'BG1234567890',
+        '1234567890',
+        'BG123456789',
+        '123456789',
+      ],
+      invalid: [
+        'BG 1234567890',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['HR'],
+      valid: [
+        'HR12345678901',
+        '12345678901',
+      ],
+      invalid: [
+        'HR 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CY'],
+      valid: [
+        'CY123456789',
+        '123456789',
+      ],
+      invalid: [
+        'CY 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CZ'],
+      valid: [
+        'CZ1234567890',
+        'CZ123456789',
+        'CZ12345678',
+        '1234567890',
+        '123456789',
+        '12345678',
+      ],
+      invalid: [
+        'CZ 123456789',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['DK'],
+      valid: [
+        'DK12345678',
+        '12345678',
+      ],
+      invalid: [
+        'DK 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['EE'],
+      valid: [
+        'EE123456789',
+        '123456789',
+      ],
+      invalid: [
+        'EE 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['FI'],
+      valid: [
+        'FI12345678',
+        '12345678',
+      ],
+      invalid: [
+        'FI 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['FR'],
+      valid: [
+        'FRAA123456789',
+        'AA123456789',
+      ],
+      invalid: [
+        'FR AA123456789',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['DE'],
+      valid: [
+        'DE123456789',
+        '123456789',
+      ],
+      invalid: [
+        'DE 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['EL'],
+      valid: [
+        'EL123456789',
+        '123456789',
+      ],
+      invalid: [
+        'EL 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['HU'],
+      valid: [
+        'HU12345678',
+        '12345678',
+      ],
+      invalid: [
+        'HU 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['IE'],
+      valid: [
+        'IE1234567AW',
+        '1234567AW',
+      ],
+      invalid: [
+        'IE 1234567',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['IT'],
+      valid: [
+        'IT12345678910',
+        '12345678910',
+      ],
+      invalid: [
+        'IT12345678 910',
+        'IT 123456789101',
+        'IT123456789101',
+        'GB12345678910',
+        'IT123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['LV'],
+      valid: [
+        'LV12345678901',
+        '12345678901',
+      ],
+      invalid: [
+        'LV 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['LT'],
+      valid: [
+        'LT123456789012',
+        '123456789012',
+        'LT12345678901',
+        '12345678901',
+        'LT1234567890',
+        '1234567890',
+        'LT123456789',
+        '123456789',
+      ],
+      invalid: [
+        'LT 123456789012',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['LU'],
+      valid: [
+        'LU12345678',
+        '12345678',
+      ],
+      invalid: [
+        'LU 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['MT'],
+      valid: [
+        'MT12345678',
+        '12345678',
+      ],
+      invalid: [
+        'MT 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['NL'],
+      valid: [
+        'NL123456789B10',
+        '123456789B10',
+      ],
+      invalid: [
+        'NL12345678 910',
+        'NL 123456789101',
+        'NL123456789B1',
+        'GB12345678910',
+        'NL123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PL'],
+      valid: [
+        'PL1234567890',
+        '1234567890',
+        'PL123-456-78-90',
+        '123-456-78-90',
+        'PL123-45-67-890',
+        '123-45-67-890',
+      ],
+      invalid: [
+        'PL 1234567890',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PT'],
+      valid: [
+        'PT123456789',
+        '123456789',
+      ],
+      invalid: [
+        'PT 123456789',
+        '000000001',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['RO'],
+      valid: [
+        'RO1234567890',
+        '1234567890',
+        'RO12',
+        '12',
+      ],
+      invalid: [
+        'RO 12',
+        '1',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SK'],
+      valid: [
+        'SK1234567890',
+        '1234567890',
+      ],
+      invalid: [
+        'SK 1234567890',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SI'],
+      valid: [
+        'SI12345678',
+        '12345678',
+      ],
+      invalid: [
+        'SI 12345678',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['ES'],
+      valid: [
+        'ESA1234567A',
+        'A1234567A',
+      ],
+      invalid: [
+        'ES 1234567A',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SE'],
+      valid: [
+        'SE123456789012',
+        '123456789012',
+      ],
+      invalid: [
+        'SE 123456789012',
+        '12345678901',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['AL'],
+      valid: [
+        'AL123456789A',
+        '123456789A',
+      ],
+      invalid: [
+        'AL 123456789A',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['MK'],
+      valid: [
+        'MK1234567890123',
+        '1234567890123',
+      ],
+      invalid: [
+        'MK 1234567890123',
+        '123456789012',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['AU'],
+      valid: [
+        'AU12345678901',
+        '12345678901',
+      ],
+      invalid: [
+        'AU 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['BY'],
+      valid: [
+        'УНП 123456789',
+        '123456789',
+      ],
+      invalid: [
+        'BY 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CA'],
+      valid: [
+        'CA123456789',
+        '123456789',
+      ],
+      invalid: [
+        'CA 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['IS'],
+      valid: [
+        'IS123456',
+        '12345',
+      ],
+      invalid: [
+        'IS 12345',
+        '1234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['IN'],
+      valid: [
+        'IN123456789012345',
+        '123456789012345',
+      ],
+      invalid: [
+        'IN 123456789012345',
+        '12345678901234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['ID'],
+      valid: [
+        'ID123456789012345',
+        '123456789012345',
+        'ID12.345.678.9-012.345',
+        '12.345.678.9-012.345',
+      ],
+      invalid: [
+        'ID 123456789012345',
+        '12345678901234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['IL'],
+      valid: [
+        'IL123456789',
+        '123456789',
+      ],
+      invalid: [
+        'IL 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['KZ'],
+      valid: [
+        'KZ123456789',
+        '123456789',
+      ],
+      invalid: [
+        'KZ 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['NZ'],
+      valid: [
+        'NZ123456789',
+        '123456789',
+      ],
+      invalid: [
+        'NZ 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['NG'],
+      valid: [
+        'NG123456789012',
+        '123456789012',
+        'NG12345678-9012',
+        '12345678-9012',
+      ],
+      invalid: [
+        'NG 123456789012',
+        '12345678901',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['NO'],
+      valid: [
+        'NO123456789MVA',
+        '123456789MVA',
+      ],
+      invalid: [
+        'NO 123456789MVA',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PH'],
+      valid: [
+        'PH123456789012',
+        '123456789012',
+        'PH123 456 789 012',
+        '123 456 789 012',
+      ],
+      invalid: [
+        'PH 123456789012',
+        '12345678901',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['RU'],
+      valid: [
+        'RU1234567890',
+        '1234567890',
+        'RU123456789012',
+        '123456789012',
+      ],
+      invalid: [
+        'RU 123456789012',
+        '12345678901',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SM'],
+      valid: [
+        'SM12345',
+        '12345',
+      ],
+      invalid: [
+        'SM 12345',
+        '1234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SA'],
+      valid: [
+        'SA123456789012345',
+        '123456789012345',
+      ],
+      invalid: [
+        'SA 123456789012345',
+        '12345678901234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['RS'],
+      valid: [
+        'RS123456789',
+        '123456789',
+      ],
+      invalid: [
+        'RS 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CH'],
+      valid: [
+        'CH123456TVA',
+        '123456TVA',
+        'CH123456789MWST',
+        '123456789MWST',
+        'CH123.456IVA',
+        '123.456IVA',
+        'CH123.456.789TVA',
+        '123.456.789TVA',
+      ],
+      invalid: [
+        'CH 123456',
+        '12345',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['TR'],
+      valid: [
+        'TR1234567890',
+        '1234567890',
+      ],
+      invalid: [
+        'TR 1234567890',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['UA'],
+      valid: [
+        'UA123456789012',
+        '123456789012',
+      ],
+      invalid: [
+        'UA 123456789012',
+        '12345678901',
+      ],
+    });
     test({
       validator: 'isVAT',
       args: ['GB'],
@@ -11946,32 +12560,242 @@ describe('Validators', () => {
     });
     test({
       validator: 'isVAT',
-      args: ['IT'],
+      args: ['UZ'],
       valid: [
-        'IT12345678910',
-        '12345678910',
+        'UZ123456789',
+        '123456789',
       ],
       invalid: [
-        'IT12345678 910',
-        'IT 123456789101',
-        'IT123456789101',
-        'GB12345678910',
-        'IT123456789',
+        'UZ 123456789',
+        '12345678',
       ],
     });
     test({
       validator: 'isVAT',
-      args: ['NL'],
+      args: ['AR'],
       valid: [
-        'NL123456789B10',
-        '123456789B10',
+        'AR12345678901',
+        '12345678901',
       ],
       invalid: [
-        'NL12345678 910',
-        'NL 123456789101',
-        'NL123456789B1',
-        'GB12345678910',
-        'NL123456789',
+        'AR 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['BO'],
+      valid: [
+        'BO1234567',
+        '1234567',
+      ],
+      invalid: [
+        'BO 1234567',
+        '123456',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['BR'],
+      valid: [
+        'BR12.345.678/9012-34',
+        '12.345.678/9012-34',
+        'BR123.456.789-01',
+        '123.456.789-01',
+      ],
+      invalid: [
+        'BR 12.345.678/9012-34',
+        '12345678901234',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CL'],
+      valid: [
+        'CL12345678-9',
+        '12345678-9',
+      ],
+      invalid: [
+        'CL 12345678-9',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CO'],
+      valid: [
+        'CO1234567890',
+        '1234567890',
+      ],
+      invalid: [
+        'CO 1234567890',
+        '123456789',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['CR'],
+      valid: [
+        'CR123456789012',
+        '123456789012',
+        'CR123456789',
+        '123456789',
+      ],
+      invalid: [
+        'CR 123456789',
+        '12345678',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['EC'],
+      valid: [
+        'EC1234567890123',
+        '1234567890123',
+      ],
+      invalid: [
+        'EC 1234567890123',
+        '123456789012',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['SV'],
+      valid: [
+        'SV1234-567890-123-1',
+        '1234-567890-123-1',
+      ],
+      invalid: [
+        'SV 1234-567890-123-1',
+        '1234567890123',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['GT'],
+      valid: [
+        'GT1234567-8',
+        '1234567-8',
+      ],
+      invalid: [
+        'GT 1234567-8',
+        '1234567',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['HN'],
+      valid: [
+        'HN',
+      ],
+      invalid: [
+        'HN ',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['MX'],
+      valid: [
+        'MXABCD123456EFG',
+        'ABCD123456EFG',
+        'MXABC123456DEF',
+        'ABC123456DEF',
+      ],
+      invalid: [
+        'MX ABC123456EFG',
+        '123456',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['NI'],
+      valid: [
+        'NI123-456789-0123A',
+        '123-456789-0123A',
+      ],
+      invalid: [
+        'NI 123-456789-0123A',
+        '1234567890123',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PA'],
+      valid: [
+        'PA',
+      ],
+      invalid: [
+        'PA ',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PY'],
+      valid: [
+        'PY12345678-9',
+        '12345678-9',
+        'PY123456-7',
+        '123456-7',
+      ],
+      invalid: [
+        'PY 123456-7',
+        '123456',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['PE'],
+      valid: [
+        'PE12345678901',
+        '12345678901',
+      ],
+      invalid: [
+        'PE 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['DO'],
+      valid: [
+        'DO12345678901',
+        '12345678901',
+        'DO123-4567890-1',
+        '123-4567890-1',
+        'DO123456789',
+        '123456789',
+        'DO1-23-45678-9',
+        '1-23-45678-9',
+      ],
+      invalid: [
+        'DO 12345678901',
+        '1234567890',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['UY'],
+      valid: [
+        'UY123456789012',
+        '123456789012',
+      ],
+      invalid: [
+        'UY 123456789012',
+        '12345678901',
+      ],
+    });
+    test({
+      validator: 'isVAT',
+      args: ['VE'],
+      valid: [
+        'VEJ-123456789',
+        'J-123456789',
+        'VEJ-12345678-9',
+        'J-12345678-9',
+      ],
+      invalid: [
+        'VE J-123456789',
+        '12345678',
       ],
     });
     test({