]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor(guards): correctly chain promises
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 31 Jul 2020 14:35:09 +0000 (16:35 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 31 Jul 2020 14:35:09 +0000 (16:35 +0200)
__tests__/guards/guardToPromiseFn.spec.ts
src/navigationGuards.ts

index 471502d80dac2739b42783423b955409b8377dbf..66c5d7291a7c0bfb6208c3f97eaed13915a291d8 100644 (file)
@@ -14,18 +14,21 @@ const from = {
 describe('guardToPromiseFn', () => {
   mockWarn()
   it('calls the guard with to, from and, next', async () => {
+    expect.assertions(2)
     const spy = jest.fn((to, from, next) => next())
     await expect(guardToPromiseFn(spy, to, from)()).resolves.toEqual(undefined)
     expect(spy).toHaveBeenCalledWith(to, from, expect.any(Function))
   })
 
   it('resolves if next is called with no arguments', async () => {
+    expect.assertions(1)
     await expect(
       guardToPromiseFn((to, from, next) => next(), to, from)()
     ).resolves.toEqual(undefined)
   })
 
   it('resolves if next is called with true', async () => {
+    expect.assertions(1)
     await expect(
       guardToPromiseFn((to, from, next) => next(true), to, from)()
     ).resolves.toEqual(undefined)
@@ -74,43 +77,36 @@ describe('guardToPromiseFn', () => {
   it('rejects if next is called with an error', async () => {
     expect.assertions(1)
     let error = new Error('nope')
-    try {
-      await guardToPromiseFn((to, from, next) => next(error), to, from)()
-    } catch (err) {
-      expect(err).toBe(error)
-    }
+    await expect(
+      guardToPromiseFn((to, from, next) => next(error), to, from)()
+    ).rejects.toBe(error)
   })
 
   it('rejects if guard rejects a Promise', async () => {
     expect.assertions(1)
-    let error = new Error('nope')
-    try {
-      await guardToPromiseFn(
+    await expect(
+      guardToPromiseFn(
         async (to, from, next) => {
-          throw error
+          throw new Error()
         },
         to,
         from
       )()
-    } catch (err) {
-      expect(err).toBe(error)
-    }
+    ).rejects.toThrowError()
   })
 
   it('rejects if guard throws an error', async () => {
     expect.assertions(1)
     let error = new Error('nope')
-    try {
-      await guardToPromiseFn(
+    await expect(
+      guardToPromiseFn(
         (to, from, next) => {
           throw error
         },
         to,
         from
       )()
-    } catch (err) {
-      expect(err).toBe(error)
-    }
+    ).rejects.toBe(error)
   })
 
   describe('no next argument', () => {
@@ -128,12 +124,14 @@ describe('guardToPromiseFn', () => {
     })
 
     it('resolves no value is returned', async () => {
+      expect.assertions(1)
       await expect(
         guardToPromiseFn((to, from) => {}, to, from)()
       ).resolves.toEqual(undefined)
     })
 
     it('resolves if true is returned', async () => {
+      expect.assertions(1)
       await expect(
         guardToPromiseFn((to, from) => true, to, from)()
       ).resolves.toEqual(undefined)
@@ -195,43 +193,36 @@ describe('guardToPromiseFn', () => {
     it('rejects if an error is returned', async () => {
       expect.assertions(1)
       let error = new Error('nope')
-      try {
-        await guardToPromiseFn((to, from) => error, to, from)()
-      } catch (err) {
-        expect(err).toBe(error)
-      }
+      await expect(
+        guardToPromiseFn((to, from) => error, to, from)()
+      ).rejects.toBe(error)
     })
 
     it('rejects if guard rejects a Promise', async () => {
       expect.assertions(1)
       let error = new Error('nope')
-      try {
-        await guardToPromiseFn(
+      await expect(
+        guardToPromiseFn(
           async (to, from) => {
             throw error
           },
           to,
           from
         )()
-      } catch (err) {
-        expect(err).toBe(error)
-      }
+      ).rejects.toBe(error)
     })
 
     it('rejects if guard throws an error', async () => {
-      expect.assertions(1)
       let error = new Error('nope')
-      try {
-        await guardToPromiseFn(
+      await expect(
+        guardToPromiseFn(
           (to, from) => {
             throw error
           },
           to,
           from
         )()
-      } catch (err) {
-        expect(err).toBe(error)
-      }
+      ).rejects.toBe(error)
     })
   })
 
@@ -239,13 +230,7 @@ describe('guardToPromiseFn', () => {
     expect.assertions(2)
     await expect(
       guardToPromiseFn((to, from, next) => false, to, from)()
-    ).rejects.toEqual(expect.any(Error))
-
-    // try {
-    //   await guardToPromiseFn((to, from, next) => false, to, from)()
-    // } catch (error) {
-    //   expect(error).toEqual(expect.any(Error))
-    // }
+    ).rejects.toThrowError()
 
     expect('callback was never called').toHaveBeenWarned()
   })
index e2e35c6da718b5bb8abf9bdec4feb222b3475925..1eebe39c117277e95f5501491af72e59b55f0839 100644 (file)
@@ -164,9 +164,9 @@ export function guardToPromiseFn(
         )
       )
 
-      if (guard.length < 3) guardCall.then(next)
+      if (guard.length < 3) guardCall = guardCall.then(next)
       if (__DEV__ && guard.length > 2)
-        guardCall.then(() => {
+        guardCall = guardCall.then(() => {
           // @ts-ignore: _called is added at canOnlyBeCalledOnce
           if (!next._called)
             warn(
@@ -174,7 +174,7 @@ export function guardToPromiseFn(
                 guard.name ? '"' + guard.name + '"' : ''
               }:\n${guard.toString()}\n. If you are returning a value instead of calling "next", make sure to remove the "next" parameter from your function.`
             )
-          reject(new Error('Invalid navigation guard'))
+          return Promise.reject(new Error('Invalid navigation guard'))
         })
       guardCall.catch(err => reject(err))
     })