Repository: validatorjs/validator.js
Pull request #2346 (2023-12-14 17:57:42)

feat(isRgbColor) Allow second digit in rgba alpha value
Updated the RegExp to allow a secondary digit for the alpha value when checking a rgba color. Added required tests and test the number of digits for the `rgbaColorPercent` RegExp.

References
Modern browsers support multiple decimals for the alpha value in rgba() color values. This is also allowed in the CSS standard: https://www.w3.org/TR/css-color-3/#transparency

## Checklist

- [x] PR contains only changes related; no stray files, etc.
- [x] README updated (where applicable)
- [x] Tests written (where applicable)
- [x] References provided in PR (where applicable)

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/validatorjs/validator.js/pull/2346?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`b958bd7`)](https://app.codecov.io/gh/validatorjs/validator.js/commit/b958bd7d1026a434ad3bf90064d3dcb8b775f1a9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) 99.95% compared to head [(`42ddf04`)](https://app.codecov.io/gh/validatorjs/validator.js/pull/2346?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) 99.95%.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #2346      +/-   ##
==========================================
- Coverage   99.95%   99.95%   -0.01%     
==========================================
  Files         107      107              
  Lines        2454     2449       -5     
  Branches      619      619              
==========================================
- Hits         2453     2448       -5     
  Partials        1        1              
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/validatorjs/validator.js/pull/2346?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).

WikiRik: I'm having a bit of trouble figuring out how many digits are allowed in the alpha value. Do you have any resources for that?
controlol: I just checked the PR by marcopixel. If this validation was intented for use with CSS I would change the current commit to use `0?\.\d+` instead of `0?\.\d{1,2}`.
Also checks should be added without a number after the dot.

Patch:
diff --git a/README.md b/README.md
index 27ae195..f05a7b8 100644
--- a/README.md
+++ b/README.md
@@ -94,7 +94,7 @@ Validator                               | Description
 **isBase32(str [, options])**           | check if the string is base32 encoded. `options` is optional and defaults to `{ crockford: false }`.<br/> When `crockford` is true it tests the given base32 encoded string using [Crockford's base32 alternative][Crockford Base32].
 **isBase58(str)**                       | check if the string is base58 encoded.
 **isBase64(str [, options])**          | check if the string is base64 encoded. `options` is optional and defaults to `{ urlSafe: false, padding: true }`<br/> when `urlSafe` is true default value for `padding` is false and it tests the given base64 encoded string is [url safe][Base64 URL Safe].
-**isBefore(str [, date])**              | check if the string is a date that is before the specified date.
+**isBefore(str [, options])**              | check if the string is a date that is before the specified date.<br/><br/>`options` is an object that defaults to `{ comparisonDate: Date().toString() }`.<br/><br/>**Options:**<br/>`comparisonDate`: Date to compare to. Defaults to `Date().toString()` (now).
 **isBIC(str)**                          | check if the string is a BIC (Bank Identification Code) or SWIFT code.
 **isBoolean(str [, options])**          | check if the string is a boolean.<br/>`options` is an object which defaults to `{ loose: false }`. If `loose` is set to false, the validator will strictly match ['true', 'false', '0', '1']. If `loose` is set to true, the validator will also match 'yes', 'no', and will match a valid boolean string of any case. (e.g.: ['true', 'True', 'TRUE']).
 **isBtcAddress(str)**            | check if the string is a valid BTC address.
diff --git a/src/lib/isAfter.js b/src/lib/isAfter.js
index e116e77..149622a 100644
--- a/src/lib/isAfter.js
+++ b/src/lib/isAfter.js
@@ -3,9 +3,10 @@ import toDate from './toDate';
 export default function isAfter(date, options) {
   // For backwards compatibility:
   // isAfter(str [, date]), i.e. `options` could be used as argument for the legacy `date`
-  const comparisonDate = options?.comparisonDate || options || Date().toString();
+  const comparisonDate = (typeof options === 'object' ? options.comparisonDate : options) || Date().toString();
 
   const comparison = toDate(comparisonDate);
   const original = toDate(date);
+
   return !!(original && comparison && original > comparison);
 }
diff --git a/src/lib/isBefore.js b/src/lib/isBefore.js
index 8314f0e..977d0ad 100644
--- a/src/lib/isBefore.js
+++ b/src/lib/isBefore.js
@@ -1,9 +1,12 @@
-import assertString from './util/assertString';
 import toDate from './toDate';
 
-export default function isBefore(str, date = String(new Date())) {
-  assertString(str);
-  const comparison = toDate(date);
-  const original = toDate(str);
+export default function isBefore(date, options) {
+  // For backwards compatibility:
+  // isBefore(str [, date]), i.e. `options` could be used as argument for the legacy `date`
+  const comparisonDate = (typeof options === 'object' ? options.comparisonDate : options) || Date().toString();
+
+  const comparison = toDate(comparisonDate);
+  const original = toDate(date);
+
   return !!(original && comparison && original < comparison);
 }
diff --git a/src/lib/isPostalCode.js b/src/lib/isPostalCode.js
index cadf393..01ae3fc 100644
--- a/src/lib/isPostalCode.js
+++ b/src/lib/isPostalCode.js
@@ -28,7 +28,7 @@ const patterns = {
   EE: fiveDigit,
   ES: /^(5[0-2]{1}|[0-4]{1}\d{1})\d{3}$/,
   FI: fiveDigit,
-  FR: /^\d{2}\s?\d{3}$/,
+  FR: /^(?:(?:0[1-9]|[1-8]\d|9[0-5])\d{3}|97[1-46]\d{2})$/,
   GB: /^(gir\s?0aa|[a-z]{1,2}\d[\da-z]?\s?(\d[a-z]{2})?)$/i,
   GR: /^\d{3}\s?\d{2}$/,
   HR: /^([1-5]\d{4}$)/,
diff --git a/src/lib/isRgbColor.js b/src/lib/isRgbColor.js
index 5267d56..6e28662 100644
--- a/src/lib/isRgbColor.js
+++ b/src/lib/isRgbColor.js
@@ -2,9 +2,9 @@
 import assertString from './util/assertString';
 
 const rgbColor = /^rgb\((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]),){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\)$/;
-const rgbaColor = /^rgba\((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]),){3}(0?\.\d|1(\.0)?|0(\.0)?)\)$/;
+const rgbaColor = /^rgba\((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]),){3}(0?\.\d\d?|1(\.0)?|0(\.0)?)\)$/;
 const rgbColorPercent = /^rgb\((([0-9]%|[1-9][0-9]%|100%),){2}([0-9]%|[1-9][0-9]%|100%)\)$/;
-const rgbaColorPercent = /^rgba\((([0-9]%|[1-9][0-9]%|100%),){3}(0?\.\d|1(\.0)?|0(\.0)?)\)$/;
+const rgbaColorPercent = /^rgba\((([0-9]%|[1-9][0-9]%|100%),){3}(0?\.\d\d?|1(\.0)?|0(\.0)?)\)$/;
 const startsWithRgb = /^rgba?/;
 
 export default function isRgbColor(str, options) {


Test patch:
diff --git a/test/validators.test.js b/test/validators.test.js
index ce2d41b..cd1ca56 100644
--- a/test/validators.test.js
+++ b/test/validators.test.js
@@ -4650,8 +4650,10 @@ describe('Validators', () => {
         'rgba(255,255,255,1)',
         'rgba(255,255,255,.1)',
         'rgba(255,255,255,0.1)',
+        'rgba(255,255,255,.12)',
         'rgb(5%,5%,5%)',
         'rgba(5%,5%,5%,.3)',
+        'rgba(5%,5%,5%,.32)',
       ],
       invalid: [
         'rgb(0,0,0,)',
@@ -4660,11 +4662,12 @@ describe('Validators', () => {
         'rgb()',
         'rgba(0,0,0)',
         'rgba(255,255,255,2)',
-        'rgba(255,255,255,.12)',
+        'rgba(255,255,255,.123)',
         'rgba(255,255,256,0.1)',
         'rgb(4,4,5%)',
         'rgba(5%,5%,5%)',
         'rgba(3,3,3%,.3)',
+        'rgba(5%,5%,5%,.321)',
         'rgb(101%,101%,101%)',
         'rgba(3%,3%,101%,0.3)',
         'rgb(101%,101%,101%) additional invalid string part',
@@ -5650,41 +5653,6 @@ describe('Validators', () => {
     });
   });
 
-  it('should validate dates against an end date', () => {
-    test({
-      validator: 'isBefore',
-      args: ['08/04/2011'],
-      valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
-      invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
-    });
-    test({
-      validator: 'isBefore',
-      args: [new Date(2011, 7, 4).toString()],
-      valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
-      invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
-    });
-    test({
-      validator: 'isBefore',
-      valid: [
-        '2000-08-04',
-        new Date(0).toString(),
-        new Date(Date.now() - 86400000).toString(),
-      ],
-      invalid: ['2100-07-02', new Date(2217, 10, 10).toString()],
-    });
-    test({
-      validator: 'isBefore',
-      args: ['2011-08-03'],
-      valid: ['1999-12-31'],
-      invalid: ['invalid date'],
-    });
-    test({
-      validator: 'isBefore',
-      args: ['invalid date'],
-      invalid: ['invalid date', '1999-12-31'],
-    });
-  });
-
   it('should validate ABA routing number', () => {
     test({
       validator: 'isAbaRouting',
@@ -12427,10 +12395,16 @@ describe('Validators', () => {
         locale: 'FR',
         valid: [
           '75008',
+          '44522',
+          '38499',
+          '39940',
+          '01000',
+        ],
+        invalid: [
           '44 522',
-          '98025',
           '38 499',
-          '39940',
+          '96000',
+          '98025',
         ],
       },
       {
diff --git a/test/validators/isAfter.test.js b/test/validators/isAfter.test.js
index d771d91..f0daf8a 100644
--- a/test/validators/isAfter.test.js
+++ b/test/validators/isAfter.test.js
@@ -27,6 +27,21 @@ describe('isAfter', () => {
       args: [{ comparisonDate: 'invalid date' }],
       invalid: ['invalid date', '2015-09-17'],
     });
+    test({
+      validator: 'isAfter',
+      args: [], // will fall back to the current date
+      valid: ['2100-08-04', new Date(Date.now() + 86400000).toString()],
+    });
+    test({
+      validator: 'isAfter',
+      args: [undefined], // will fall back to the current date
+      valid: ['2100-08-04', new Date(Date.now() + 86400000).toString()],
+    });
+    test({
+      validator: 'isAfter',
+      args: [{ comparisonDate: undefined }], // will fall back to the current date
+      valid: ['2100-08-04', new Date(Date.now() + 86400000).toString()],
+    });
   });
 
   describe('(legacy syntax)', () => {
diff --git a/test/validators/isBefore.test.js b/test/validators/isBefore.test.js
new file mode 100644
index 0000000..298e5b4
--- /dev/null
+++ b/test/validators/isBefore.test.js
@@ -0,0 +1,119 @@
+import { describe } from 'mocha';
+import test from '../testFunctions';
+
+describe('isBefore', () => {
+  describe('should validate dates a given end date', () => {
+    describe('new syntax', () => {
+      test({
+        validator: 'isBefore',
+        args: [{ comparisonDate: '08/04/2011' }],
+        valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
+        invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: [{ comparisonDate: new Date(2011, 7, 4).toString() }],
+        valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
+        invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: [{ comparisonDate: '2011-08-03' }],
+        valid: ['1999-12-31'],
+        invalid: ['invalid date'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [{ comparisonDate: 'invalid date' }],
+        invalid: ['invalid date', '1999-12-31'],
+      });
+    });
+
+    describe('legacy syntax', () => {
+      test({
+        validator: 'isBefore',
+        args: ['08/04/2011'],
+        valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
+        invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: [new Date(2011, 7, 4).toString()],
+        valid: ['2010-07-02', '2010-08-04', new Date(0).toString()],
+        invalid: ['08/04/2011', new Date(2011, 9, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: ['2011-08-03'],
+        valid: ['1999-12-31'],
+        invalid: ['invalid date'],
+      });
+      test({
+        validator: 'isBefore',
+        args: ['invalid date'],
+        invalid: ['invalid date', '1999-12-31'],
+      });
+    });
+  });
+
+  describe('should validate dates a default end date', () => {
+    describe('new syntax', () => {
+      test({
+        validator: 'isBefore',
+        valid: [
+          '2000-08-04',
+          new Date(0).toString(),
+          new Date(Date.now() - 86400000).toString(),
+        ],
+        invalid: ['2100-07-02', new Date(2217, 10, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: undefined, // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [], // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [undefined], // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [{ comparisonDate: undefined }], // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+    });
+
+    describe('legacy syntax', () => {
+      test({
+        validator: 'isBefore',
+        valid: [
+          '2000-08-04',
+          new Date(0).toString(),
+          new Date(Date.now() - 86400000).toString(),
+        ],
+        invalid: ['2100-07-02', new Date(2217, 10, 10).toString()],
+      });
+      test({
+        validator: 'isBefore',
+        args: undefined, // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [], // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+      test({
+        validator: 'isBefore',
+        args: [undefined], // will fall back to the current date
+        valid: ['1999-06-07'],
+      });
+    });
+  });
+});