Repository: validatorjs/validator.js
Pull request #2088 (2022-10-25 14:05:01)

feat(isBefore): allow usage of options object
This PR implements steps 1 and 2 of https://github.com/validatorjs/validator.js/issues/1874 for `isBefore` and builds upon https://github.com/validatorjs/validator.js/pull/2075.

This PR extracts tests for `isBefore` into a separate test file ⇾ `test/validators/isBefore.test.js` (inspired by https://github.com/validatorjs/validator.js/pull/1793).

This PR also renames the proposed `date` option to `comparisonDate`, because it is more explicit. If verified, it should be implemented in https://github.com/validatorjs/validator.js/pull/2075 as well.

## Checklist

- [x] PR contains only changes related; no stray files, etc.
- [x] README updated (where applicable)
- [x] Tests written (where applicable)


codecov[bot]: # [Codecov](https://codecov.io/gh/validatorjs/validator.js/pull/2088?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) Report
Base: **100.00**% // Head: **100.00**% // No change to project coverage :thumbsup:
> Coverage data is based on head [(`50318a3`)](https://codecov.io/gh/validatorjs/validator.js/pull/2088?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) compared to base [(`7b47f53`)](https://codecov.io/gh/validatorjs/validator.js/commit/7b47f533b4061850db5c1ed0be8ac47e7e80e4ee?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).
> Patch coverage: 100.00% of modified lines in pull request are covered.

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


```diff
@@            Coverage Diff            @@
##            master     #2088   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          104       104           
  Lines         2308      2309    +1     
  Branches       578       578           
=========================================
+ Hits          2308      2309    +1     
```


| [Impacted Files](https://codecov.io/gh/validatorjs/validator.js/pull/2088?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs) | Coverage Δ | |
|---|---|---|
| [src/lib/isAfter.js](https://codecov.io/gh/validatorjs/validator.js/pull/2088/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs#diff-c3JjL2xpYi9pc0FmdGVyLmpz) | `100.00% <100.00%> (ø)` | |
| [src/lib/isBefore.js](https://codecov.io/gh/validatorjs/validator.js/pull/2088/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs#diff-c3JjL2xpYi9pc0JlZm9yZS5qcw==) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/validatorjs/validator.js/pull/2088?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=validatorjs).

pixelbucket-dev: I think this should be good to go :).

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}$)/,


Test patch:
diff --git a/test/validators.test.js b/test/validators.test.js
index ce2d41b..ed28755 100644
--- a/test/validators.test.js
+++ b/test/validators.test.js
@@ -5650,41 +5650,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 +12392,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'],
+      });
+    });
+  });
+});