Repository: jquense/yup (ts)

Issue:
Throws error when there's none
Hi, I do my validation on a controller and I test it with Jest. This is the exception thrown:

```
ValidationError {
      name: 'ValidationError',
      value:
       { companyName: 'TTT Company name',
         companyAddress: 'TTT Company address',
         companyCity: 'TTT Company city',
         companyZipcode: 'G0G0G0',
         firstname: 'TTT firstname',
         lastname: 'TTT lastname',
         tel: '418-999-9999',
         email: 'TTTemail@myadress.com',
         password: '!A1234567!',
         passwordConfirmation: '!A1234567!',
         rbq: 'rbq12345678',
         neq: 'neq12345678',
         tvq: 'tvq12345678',
         tps: 'tps12345678',
         cognitoSub: 'cognito sub',
         subscribeEmail: true },
      path: undefined,
      type: undefined,
      errors:
       [ 'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"' ],
      inner:
       [ ValidationError {
           name: 'ValidationError',
           value: 'G0G0G0',
           path: 'companyZipcode',
           type: undefined,
           errors: [Array],
           inner: [],
           message:
            'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"',
           params: [Object] } ],
      message:
       'companyZipcode must match the following: "/([A-Z]\\d[A-Z]\\s?\\d[A-Z]\\d)/gi"' }
```

It been thrown on the second part of my test suite. The two are exactly the same, but the second fails.

```
describe('ContactsController', () => {
  test('method create creates a company correctly', async function(done) {
    const client = new AxiosClient({})

    // override Axios post to return mocked response
    mockAxios.post = jest
      .fn()
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseCompanyData)
      )
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseContactData)
      )

    const validator = new DataValidator(ContactCreationSchema)
    const transformer = new ContactCreationTransformer([
      'companyName',
      'companyAddress',
      'companyCity',
      'companyZipcode',
      'firstname',
      'lastname',
      'tel',
      'email',
      'password',
      'passwordConfirmation',
      'rbq',
      'neq',
      'tvq',
      'tps',
      'cognitoSub',
      'subscribeEmail',
    ])

    const controller = new ContactsController(client, validator, transformer)
    const contact = await controller.create(ContactCreationTransformer_rawData)

    expect(mockAxios.post).toHaveBeenCalledTimes(2)
    expect(contact).toEqual(ContactCreationTransformer_transformedResponseData)

    done()
  })

  test('method create throws on error', async function(done) {
    const client = new AxiosClient({})

    // override Axios post to return mocked response
    mockAxios.post = jest
      .fn()
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseCompanyData)
      )
      .mockImplementationOnce(() =>
        Promise.resolve(ContactCreationTransformer_responseContactData)
      )

    const validator = new DataValidator(ContactCreationSchema)
    const transformer = new ContactCreationTransformer([
      'companyName',
      'companyAddress',
      'companyCity',
      'companyZipcode',
      'firstname',
      'lastname',
      'tel',
      'email',
      'password',
      'passwordConfirmation',
      'rbq',
      'neq',
      'tvq',
      'tps',
      'cognitoSub',
      'subscribeEmail',
    ])

    const controller = new ContactsController(client, validator, transformer)
    const contact = await controller.create(ContactCreationTransformer_rawData)

    expect(mockAxios.post).toHaveBeenCalledTimes(2)
    expect(contact).toEqual(ContactCreationTransformer_transformedResponseData)

    done()
  })
})
```

And this is is the regex to validate `companyZipcode` without the escaped backslashes

`/([A-Z]\d[A-Z]\s?\d[A-Z]\d)/gi`

What is going on? Did I forgot to reset the schema or something?

It do this on every second test case using validation on Zipcode/Postal Code.

Thank you very much for your help

Pull request description:
fix: string.matches() and regex global flag
Fixes #442

Patch:
diff --git a/src/number.js b/src/number.js
index be65452..b179e6a 100644
--- a/src/number.js
+++ b/src/number.js
@@ -5,8 +5,6 @@ import isAbsent from './util/isAbsent';
 
 let isNaN = value => value != +value;
 
-let isInteger = val => isAbsent(val) || val === (val | 0);
-
 export default function NumberSchema() {
   if (!(this instanceof NumberSchema)) return new NumberSchema();
 
@@ -14,8 +12,8 @@ export default function NumberSchema() {
 
   this.withMutation(() => {
     this.transform(function(value) {
-      let parsed = value
-      
+      let parsed = value;
+
       if (typeof parsed === 'string') {
         parsed = parsed.replace(/\s/g, '');
         if (parsed === '') return NaN;
@@ -94,7 +92,11 @@ inherits(NumberSchema, MixedSchema, {
   },
 
   integer(message = locale.integer) {
-    return this.test({ name: 'integer', message, test: isInteger });
+    return this.test({
+      name: 'integer',
+      message,
+      test: val => isAbsent(val) || Number.isInteger(val),
+    });
   },
 
   truncate() {
diff --git a/src/string.js b/src/string.js
index 01bb428..1133c9d 100644
--- a/src/string.js
+++ b/src/string.js
@@ -86,7 +86,7 @@ inherits(StringSchema, MixedSchema, {
       test: value =>
         isAbsent(value) ||
         (value === '' && excludeEmptyString) ||
-        regex.test(value),
+        value.search(regex) !== -1,
     });
   },
 


Test patch:
diff --git a/test/number.js b/test/number.js
index 4d9144b..651873d 100644
--- a/test/number.js
+++ b/test/number.js
@@ -203,8 +203,8 @@ describe('Number types', function() {
     var schema = number().integer();
 
     TestHelpers.validateAll(schema, {
-      valid: [4, -5222],
-      invalid: [10.53, 0.1 * 0.2, -34512535.626, 3.12312e51, new Date()],
+      valid: [4, -5222, 3.12312e51],
+      invalid: [10.53, 0.1 * 0.2, -34512535.626, new Date()],
     });
 
     it('should return default message', () => {
diff --git a/test/string.js b/test/string.js
index d99a144..55ebf8e 100644
--- a/test/string.js
+++ b/test/string.js
@@ -149,6 +149,21 @@ describe('String types', () => {
     ]);
   });
 
+  it('should check MATCHES correctly with global and sticky flags', function() {
+    var v = string().matches(/hi/gy);
+
+    return Promise.all([
+      v
+        .isValid('hi')
+        .should.eventually()
+        .equal(true),
+      v
+        .isValid('hi')
+        .should.eventually()
+        .equal(true),
+    ]);
+  });
+
   it('MATCHES should include empty strings', () => {
     let v = string().matches(/(hi|bye)/);