]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
refactor(test): replace custom testing utils with VTU (#695)
authoredison <daiwei521@126.com>
Thu, 7 Jan 2021 09:07:23 +0000 (17:07 +0800)
committerGitHub <noreply@github.com>
Thu, 7 Jan 2021 09:07:23 +0000 (10:07 +0100)
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com>
__tests__/RouterLink.spec.ts
__tests__/RouterView.spec.ts
__tests__/guards/beforeRouteEnterCallback.spec.ts
__tests__/mount.ts
package.json
yarn.lock

index c2af1951a31adf5a9e7cb75323ebccef38287825..4aa877c93fbf502935226ed12cb50b8384750e81 100644 (file)
@@ -9,11 +9,12 @@ import {
   RouteLocationNormalized,
 } from '../src/types'
 import { createMemoryHistory, RouterOptions } from '../src'
-import { mount, createMockedRoute } from './mount'
-import { defineComponent, nextTick, PropType } from 'vue'
+import { createMockedRoute } from './mount'
+import { defineComponent, PropType } from 'vue'
 import { RouteRecordNormalized } from '../src/matcher/types'
 import { routerKey } from '../src/injectionSymbols'
 import { tick } from './utils'
+import { mount } from '@vue/test-utils'
 
 const records = {
   home: {} as RouteRecordNormalized,
@@ -371,11 +372,13 @@ async function factory(
   }
   router.resolve.mockReturnValueOnce(resolvedLocation)
 
-  const wrapper = await mount(RouterLink, {
+  const wrapper = mount(RouterLink as any, {
     propsData,
-    provide: {
-      [routerKey as any]: router,
-      ...route.provides,
+    global: {
+      provide: {
+        [routerKey as any]: router,
+        ...route.provides,
+      },
     },
     slots: { default: slotTemplate },
   })
@@ -390,7 +393,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.getAttribute('href')).toBe('/home')
+    expect(wrapper.find('a')!.attributes('href')).toBe('/home')
   })
 
   it('can change the value', async () => {
@@ -399,10 +402,10 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.getAttribute('href')).toBe('/home')
+    expect(wrapper.find('a')!.attributes('href')).toBe('/home')
     router.resolve.mockReturnValueOnce(locations.foo.normalized)
     await wrapper.setProps({ to: locations.foo.string })
-    expect(wrapper.find('a')!.getAttribute('href')).toBe('/foo')
+    expect(wrapper.find('a')!.attributes('href')).toBe('/foo')
   })
 
   it('displays a link with an object with path prop', async () => {
@@ -411,7 +414,7 @@ describe('RouterLink', () => {
       { to: { path: locations.basic.string } },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.getAttribute('href')).toBe('/home')
+    expect(wrapper.find('a')!.attributes('href')).toBe('/home')
   })
 
   it('can be active', async () => {
@@ -420,7 +423,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
+    expect(wrapper.find('a').classes()).toContain('router-link-active')
   })
 
   it('sets aria-current to page by default when exact active', async () => {
@@ -429,10 +432,10 @@ describe('RouterLink', () => {
       { to: locations.parent.string },
       locations.parent.normalized
     )
-    expect(wrapper.find('a')!.getAttribute('aria-current')).toBe('page')
+    expect(wrapper.find('a')!.attributes('aria-current')).toBe('page')
     route.set(locations.child.normalized)
     await tick()
-    expect(wrapper.find('a')!.getAttribute('aria-current')).not.toBe('page')
+    expect(wrapper.find('a')!.attributes('aria-current')).not.toBe('page')
   })
 
   it('can customize aria-current value', async () => {
@@ -441,7 +444,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string, ariaCurrentValue: 'time' },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.getAttribute('aria-current')).toBe('time')
+    expect(wrapper.find('a')!.attributes('aria-current')).toBe('time')
   })
 
   it('can customize active class', async () => {
@@ -450,8 +453,8 @@ describe('RouterLink', () => {
       { to: locations.basic.string, activeClass: 'is-active' },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).not.toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('is-active')
+    expect(wrapper.find('a')!.classes()).not.toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('is-active')
   })
 
   it('prop classes take over global', async () => {
@@ -470,14 +473,14 @@ describe('RouterLink', () => {
     // force render because options is not reactive
     router.resolve.mockReturnValueOnce(locations.basic.normalized)
     await wrapper.setProps({ to: locations.basic.string })
-    expect(wrapper.find('a')!.className).not.toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).not.toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
-    expect(wrapper.find('a')!.className).not.toContain('custom')
-    expect(wrapper.find('a')!.className).not.toContain('custom-exact')
-    expect(wrapper.find('a')!.className).toContain('is-active')
-    expect(wrapper.find('a')!.className).toContain('is-exact')
+    expect(wrapper.find('a')!.classes()).not.toContain('custom')
+    expect(wrapper.find('a')!.classes()).not.toContain('custom-exact')
+    expect(wrapper.find('a')!.classes()).toContain('is-active')
+    expect(wrapper.find('a')!.classes()).toContain('is-exact')
   })
 
   it('can globally customize active class', async () => {
@@ -491,8 +494,8 @@ describe('RouterLink', () => {
     // force render because options is not reactive
     router.resolve.mockReturnValueOnce(locations.basic.normalized)
     await wrapper.setProps({ to: locations.basic.string })
-    expect(wrapper.find('a')!.className).not.toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('custom')
+    expect(wrapper.find('a')!.classes()).not.toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('custom')
   })
 
   it('can globally customize exact active class', async () => {
@@ -506,10 +509,10 @@ describe('RouterLink', () => {
     // force render because options is not reactive
     router.resolve.mockReturnValueOnce(locations.basic.normalized)
     await wrapper.setProps({ to: locations.basic.string })
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
-    expect(wrapper.find('a')!.className).toContain('custom')
+    expect(wrapper.find('a')!.classes()).toContain('custom')
   })
 
   it('can customize exact active class', async () => {
@@ -518,10 +521,10 @@ describe('RouterLink', () => {
       { to: locations.basic.string, exactActiveClass: 'is-active' },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
-    expect(wrapper.find('a')!.className).toContain('is-active')
+    expect(wrapper.find('a')!.classes()).toContain('is-active')
   })
 
   it('can be active with custom class', async () => {
@@ -530,8 +533,8 @@ describe('RouterLink', () => {
       { to: locations.basic.string, class: 'nav-item' },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('nav-item')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('nav-item')
   })
 
   it('is not active on a non matched location', async () => {
@@ -540,7 +543,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).toBe('')
+    expect(wrapper.find('a')!.classes()).toHaveLength(0)
   })
 
   it('is not active with different params type', async () => {
@@ -549,7 +552,7 @@ describe('RouterLink', () => {
       { to: locations.singleStringParams.string },
       locations.singleStringParams.normalized
     )
-    expect(wrapper.find('a')!.className).toBe('')
+    expect(wrapper.find('a')!.classes()).toHaveLength(0)
   })
 
   it('is not active with different repeated params', async () => {
@@ -558,7 +561,7 @@ describe('RouterLink', () => {
       { to: locations.anotherRepeatedParams2.string },
       locations.anotherRepeatedParams2.normalized
     )
-    expect(wrapper.find('a')!.className).toBe('')
+    expect(wrapper.find('a')!.classes()).toHaveLength(0)
   })
 
   it('is not active with more repeated params', async () => {
@@ -567,7 +570,7 @@ describe('RouterLink', () => {
       { to: locations.repeatedParams3.string },
       locations.repeatedParams3.normalized
     )
-    expect(wrapper.find('a')!.className).toBe('')
+    expect(wrapper.find('a')!.classes()).toHaveLength(0)
   })
 
   it('is not active with partial repeated params', async () => {
@@ -576,7 +579,7 @@ describe('RouterLink', () => {
       { to: locations.repeatedParams2.string },
       locations.repeatedParams2.normalized
     )
-    expect(wrapper.find('a')!.className).toBe('')
+    expect(wrapper.find('a')!.classes()).toHaveLength(0)
   })
 
   it('can be active as an alias', async () => {
@@ -585,8 +588,8 @@ describe('RouterLink', () => {
       { to: locations.alias.string },
       locations.alias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
     wrapper = (
       await factory(
         locations.alias.normalized,
@@ -594,8 +597,8 @@ describe('RouterLink', () => {
         locations.basic.normalized
       )
     ).wrapper
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
   })
 
   it('is active when a child is active', async () => {
@@ -604,8 +607,8 @@ describe('RouterLink', () => {
       { to: locations.parent.string },
       locations.parent.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -616,8 +619,8 @@ describe('RouterLink', () => {
       { to: locations.child.string },
       locations.child.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
   })
 
   it('child is not active if the parent is active', async () => {
@@ -626,8 +629,8 @@ describe('RouterLink', () => {
       { to: locations.child.string },
       locations.child.normalized
     )
-    expect(wrapper.find('a')!.className).not.toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).not.toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -638,8 +641,8 @@ describe('RouterLink', () => {
       { to: locations.parent.string },
       locations.parent.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -650,8 +653,8 @@ describe('RouterLink', () => {
       { to: locations.childEmpty.string },
       locations.childEmpty.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -662,8 +665,8 @@ describe('RouterLink', () => {
       { to: locations.childEmptyAlias.string },
       locations.childEmptyAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -674,8 +677,8 @@ describe('RouterLink', () => {
       { to: locations.childEmpty.string },
       locations.childEmpty.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -686,8 +689,8 @@ describe('RouterLink', () => {
       { to: locations.childEmptyAlias.string },
       locations.childEmptyAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -698,8 +701,8 @@ describe('RouterLink', () => {
       { to: locations.parentAlias.string },
       locations.parentAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -710,8 +713,8 @@ describe('RouterLink', () => {
       { to: locations.parentAlias.string },
       locations.parentAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
     wrapper = (
@@ -721,8 +724,8 @@ describe('RouterLink', () => {
         locations.parentAlias.normalized
       )
     ).wrapper
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).not.toContain(
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).not.toContain(
       'router-link-exact-active'
     )
   })
@@ -733,8 +736,8 @@ describe('RouterLink', () => {
       { to: locations.parentAlias.string },
       locations.parentAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
 
     wrapper = (
       await factory(
@@ -743,8 +746,8 @@ describe('RouterLink', () => {
         locations.parent.normalized
       )
     ).wrapper
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
   })
 
   it('child and parent with alias', async () => {
@@ -753,8 +756,8 @@ describe('RouterLink', () => {
       { to: locations.childDoubleAlias.string },
       locations.childDoubleAlias.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
 
     wrapper = (
       await factory(
@@ -763,8 +766,8 @@ describe('RouterLink', () => {
         locations.childParentAlias.normalized
       )
     ).wrapper
-    expect(wrapper.find('a')!.className).toContain('router-link-active')
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
   })
 
   it('can be exact-active', async () => {
@@ -773,7 +776,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    expect(wrapper.find('a')!.className).toContain('router-link-exact-active')
+    expect(wrapper.find('a')!.classes()).toContain('router-link-exact-active')
   })
 
   it('calls ensureLocation', async () => {
@@ -792,8 +795,7 @@ describe('RouterLink', () => {
       { to: locations.basic.string },
       locations.basic.normalized
     )
-    wrapper.find('a')!.click()
-    await nextTick()
+    wrapper.find('a')!.trigger('click')
     expect(router.push).toHaveBeenCalledTimes(1)
   })
 
@@ -803,8 +805,7 @@ describe('RouterLink', () => {
       { to: locations.alias.string },
       locations.alias.normalized
     )
-    wrapper.find('a')!.click()
-    await nextTick()
+    wrapper.find('a')!.trigger('click')
     expect(router.push).toHaveBeenCalledTimes(1)
     expect(router.push).not.toHaveBeenCalledWith(
       expect.objectContaining({
@@ -817,12 +818,14 @@ describe('RouterLink', () => {
 
   describe('v-slot', () => {
     const slotTemplate = `
+      <template #default="{ route, href, isActive, isExactActive }">
         <span>
           route: {{ JSON.stringify(route) }}
           href: "{{ href }}"
           isActive: "{{ isActive }}"
           isExactActive: "{{ isExactActive }}"
         </span>
+      </template>
     `
 
     it('provides information on v-slot', async () => {
@@ -844,8 +847,8 @@ describe('RouterLink', () => {
         slotTemplate
       )
 
-      expect(wrapper.rootEl.children[0].tagName).toBe('A')
-      expect(wrapper.rootEl.children).toHaveLength(1)
+      expect(wrapper.element.tagName).toBe('A')
+      expect(wrapper.element.childElementCount).toBe(1)
     })
 
     it('can customize the rendering and remove the wrapping `a`', async () => {
@@ -911,11 +914,13 @@ describe('RouterLink', () => {
         }
         router.resolve.mockReturnValueOnce(resolvedLocation)
 
-        const wrapper = await mount(AppLink, {
+        const wrapper = await mount(AppLink as any, {
           propsData,
-          provide: {
-            [routerKey as any]: router,
-            ...route.provides,
+          global: {
+            provide: {
+              [routerKey as any]: router,
+              ...route.provides,
+            },
           },
           slots: { default: slotTemplate },
         })
@@ -934,7 +939,7 @@ describe('RouterLink', () => {
           locations.foo.normalized
         )
 
-        expect(wrapper.find('a')!.className).toEqual('inactive')
+        expect(wrapper.find('a')!.classes()).toEqual(['inactive'])
       })
 
       it('can extend RouterLink with external link', async () => {
@@ -946,8 +951,8 @@ describe('RouterLink', () => {
           locations.foo.normalized
         )
 
-        expect(wrapper.find('a')!.className).toEqual('')
-        expect(wrapper.find('a')!.href).toEqual('https://esm.dev/')
+        expect(wrapper.find('a')!.classes()).toHaveLength(0)
+        expect(wrapper.find('a')!.attributes('href')).toEqual('https://esm.dev')
       })
     })
   })
index 83f3017bb65fa30931c85e4f4dba96a7de1ad25f..f1ae2c98b5ba9f58491188c258cbb7656b6ddc0f 100644 (file)
@@ -8,8 +8,9 @@ import {
   RouteLocationNormalized,
 } from '../src/types'
 import { markRaw } from 'vue'
-import { mount, createMockedRoute } from './mount'
+import { createMockedRoute } from './mount'
 import { mockWarn } from 'jest-mock-warn'
+import { mount } from '@vue/test-utils'
 
 // to have autocompletion
 function createRoutes<T extends Record<string, RouteLocationNormalizedLoose>>(
@@ -211,10 +212,12 @@ describe('RouterView', () => {
     propsData: any = {}
   ) {
     const route = createMockedRoute(initialRoute)
-    const wrapper = await mount(RouterView, {
+    const wrapper = mount(RouterView as any, {
       propsData,
-      provide: route.provides,
-      components: { RouterView },
+      global: {
+        provide: route.provides,
+        components: { RouterView },
+      },
     })
 
     return { route, wrapper }
@@ -234,7 +237,7 @@ describe('RouterView', () => {
     const { wrapper } = await factory(START_LOCATION_NORMALIZED as any)
     // NOTE: I wonder if this will stay stable in future releases
     expect('Router').not.toHaveBeenWarned()
-    expect(wrapper.rootEl.childElementCount).toBe(0)
+    expect(wrapper.element.childNodes).toHaveLength(0)
   })
 
   it('displays nested views', async () => {
@@ -308,9 +311,9 @@ describe('RouterView', () => {
   })
 
   describe('warnings', () => {
-    it('does not warn RouterView is wrapped', async () => {
+    it('does not warn RouterView is wrapped', () => {
       const route = createMockedRoute(routes.root)
-      const wrapper = await mount(
+      const wrapper = mount(
         {
           template: `
         <div>
@@ -320,17 +323,19 @@ describe('RouterView', () => {
         },
         {
           propsData: {},
-          provide: route.provides,
-          components: { RouterView },
+          global: {
+            provide: route.provides,
+            components: { RouterView },
+          },
         }
       )
       expect(wrapper.html()).toBe(`<div><div>Home</div></div>`)
       expect('can no longer be used directly inside').not.toHaveBeenWarned()
     })
 
-    it('warns if KeepAlive wraps a RouterView', async () => {
+    it('warns if KeepAlive wraps a RouterView', () => {
       const route = createMockedRoute(routes.root)
-      const wrapper = await mount(
+      const wrapper = mount(
         {
           template: `
         <keep-alive>
@@ -340,8 +345,10 @@ describe('RouterView', () => {
         },
         {
           propsData: {},
-          provide: route.provides,
-          components: { RouterView },
+          global: {
+            provide: route.provides,
+            components: { RouterView },
+          },
         }
       )
       expect(wrapper.html()).toBe(`<div>Home</div>`)
@@ -350,7 +357,7 @@ describe('RouterView', () => {
 
     it('warns if KeepAlive and Transition wrap a RouterView', async () => {
       const route = createMockedRoute(routes.root)
-      const wrapper = await mount(
+      const wrapper = mount(
         {
           template: `
         <transition>
@@ -362,17 +369,22 @@ describe('RouterView', () => {
         },
         {
           propsData: {},
-          provide: route.provides,
-          components: { RouterView },
+          global: {
+            stubs: {
+              transition: false,
+            },
+            provide: route.provides,
+            components: { RouterView },
+          },
         }
       )
       expect(wrapper.html()).toBe(`<div>Home</div>`)
       expect('can no longer be used directly inside').toHaveBeenWarned()
     })
 
-    it('warns if Transition wraps a RouterView', async () => {
+    it('warns if Transition wraps a RouterView', () => {
       const route = createMockedRoute(routes.root)
-      const wrapper = await mount(
+      const wrapper = mount(
         {
           template: `
         <transition>
@@ -382,8 +394,13 @@ describe('RouterView', () => {
         },
         {
           propsData: {},
-          provide: route.provides,
-          components: { RouterView },
+          global: {
+            stubs: {
+              transition: false,
+            },
+            provide: route.provides,
+            components: { RouterView },
+          },
         }
       )
       expect(wrapper.html()).toBe(`<div>Home</div>`)
@@ -397,15 +414,18 @@ describe('RouterView', () => {
       propsData: any = {}
     ) {
       const route = createMockedRoute(initialRoute)
-      const wrapper = await mount(RouterView, {
+      const wrapper = await mount(RouterView as any, {
         propsData,
-        provide: route.provides,
-        components: { RouterView },
+        global: {
+          provide: route.provides,
+          components: { RouterView },
+        },
         slots: {
           default: `
-          <span>{{ route.name }}</span>
-          <component :is="Component"/>
-        `,
+            <template #default="{ route, Component }">
+              <span>{{ route.name }}</span>
+              <component :is="Component"/>
+            </template>`,
         },
       })
 
@@ -424,16 +444,19 @@ describe('RouterView', () => {
       propsData: any = {}
     ) {
       const route = createMockedRoute(initialRoute)
-      const wrapper = await mount(RouterView, {
+      const wrapper = await mount(RouterView as any, {
         propsData,
-        provide: route.provides,
-        components: { RouterView },
+        global: {
+          provide: route.provides,
+          components: { RouterView },
+        },
         slots: {
           default: `
-          <keep-alive>
-            <component :is="Component"/>
-          </keep-alive>
-        `,
+          <template #default="{ Component }">
+            <keep-alive>
+              <component :is="Component"/>
+            </keep-alive>
+          </template>`,
         },
       })
 
index b223c77093c4451e7d3c71d1862b26f1b3120277..6b66349d0fb85aa00a9d5343e804c83c94ed3bf5 100644 (file)
@@ -2,7 +2,7 @@
  * @jest-environment jsdom
  */
 import { defineComponent, h } from 'vue'
-import { mount } from '../mount'
+import { mount } from '@vue/test-utils'
 import {
   createRouter,
   RouterView,
@@ -56,7 +56,7 @@ describe('beforeRouteEnter next callback', () => {
       ...options,
     })
 
-    const wrapper = await mount(
+    const wrapper = mount(
       {
         template: `
       <div>
@@ -64,9 +64,13 @@ describe('beforeRouteEnter next callback', () => {
         <router-view name="other"/>
       </div>
       `,
-        components: { RouterView },
       },
-      { router }
+      {
+        global: {
+          plugins: [router],
+          components: { RouterView },
+        },
+      }
     )
 
     return { wrapper, router }
index 41976e4332cc2b9e05516fcc354414411f548666..476012507e842cca76a30e2ccd2081ccef14d983 100644 (file)
@@ -1,162 +1,9 @@
-import {
-  createApp,
-  defineComponent,
-  h,
-  ComponentPublicInstance,
-  reactive,
-  nextTick,
-  ComponentObjectPropsOptions,
-  ComputedRef,
-  computed,
-  App,
-  VNode,
-  shallowRef,
-  ComponentOptions,
-} from 'vue'
-import { compile } from '@vue/compiler-dom'
-import * as runtimeDom from '@vue/runtime-dom'
+import { reactive, nextTick, ComputedRef, computed, shallowRef } from 'vue'
 import { RouteLocationNormalizedLoose } from './utils'
 import {
   routeLocationKey,
   routerViewLocationKey,
 } from '../src/injectionSymbols'
-import { Router } from '../src'
-
-export interface MountOptions {
-  propsData: Record<string, any>
-  provide: Record<string | symbol, any>
-  components: ComponentOptions['components']
-  slots: Record<string, string>
-  router?: Router
-}
-
-interface Wrapper {
-  app: App
-  vm: ComponentPublicInstance
-  rootEl: HTMLDivElement
-  setProps(props: MountOptions['propsData']): Promise<void>
-  html(): string
-  find: typeof document['querySelector']
-}
-
-function initialProps<P>(propsOption: ComponentObjectPropsOptions<P>) {
-  let copy = {} as ComponentPublicInstance<typeof propsOption>['$props']
-
-  for (let key in propsOption) {
-    const prop = propsOption[key]!
-    // @ts-ignore
-    if (!prop.required && prop.default)
-      // @ts-ignore
-      copy[key] = prop.default
-  }
-
-  return copy
-}
-
-// cleanup wrappers after a suite runs
-let activeWrapperRemovers: Array<() => void> = []
-afterAll(() => {
-  activeWrapperRemovers.forEach(remove => remove())
-  activeWrapperRemovers = []
-})
-
-export function mount(
-  targetComponent: Parameters<typeof createApp>[0],
-  options: Partial<MountOptions> = {}
-): Promise<Wrapper> {
-  const TargetComponent = targetComponent
-  return new Promise(resolve => {
-    // NOTE: only supports props as an object
-    const propsData = reactive(
-      Object.assign(
-        initialProps(
-          // @ts-ignore
-          TargetComponent.props || {}
-        ),
-        options.propsData
-      )
-    )
-
-    function setProps(partialProps: Record<string, any>) {
-      Object.assign(propsData, partialProps)
-      return nextTick()
-    }
-
-    let slots: Record<string, (propsData: any) => VNode> = {}
-
-    const Wrapper = defineComponent({
-      setup(_props, { emit }) {
-        const componentInstanceRef = shallowRef<ComponentPublicInstance>()
-
-        return () => {
-          return h(
-            TargetComponent as any,
-            {
-              ref: componentInstanceRef,
-              onVnodeMounted() {
-                emit('ready', componentInstanceRef.value)
-              },
-              ...propsData,
-            },
-            slots
-          )
-        }
-      },
-    })
-
-    const app = createApp(Wrapper, {
-      onReady: (instance: ComponentPublicInstance) => {
-        resolve({ app, vm: instance!, rootEl, setProps, html, find })
-      },
-    })
-
-    if (options.provide) {
-      const keys = getKeys(options.provide)
-
-      for (let key of keys) {
-        app.provide(key, options.provide[key as any])
-      }
-    }
-
-    if (options.components) {
-      for (let key in options.components) {
-        app.component(key, options.components[key])
-      }
-    }
-
-    if (options.slots) {
-      for (let key in options.slots) {
-        slots[key] = compileSlot(options.slots[key])
-      }
-    }
-
-    const rootEl = document.createElement('div')
-    document.body.appendChild(rootEl)
-
-    function html() {
-      return rootEl.innerHTML
-    }
-
-    function find(selector: string) {
-      return rootEl.querySelector(selector)
-    }
-
-    if (options.router) app.use(options.router)
-
-    app.mount(rootEl)
-
-    activeWrapperRemovers.push(() => {
-      app.unmount(rootEl)
-      rootEl.remove()
-    })
-  })
-}
-
-function getKeys(object: Record<string | symbol, any>): Array<symbol | string> {
-  return (Object.getOwnPropertyNames(object) as Array<string | symbol>).concat(
-    Object.getOwnPropertySymbols(object)
-  )
-}
 
 export function createMockedRoute(initialValue: RouteLocationNormalizedLoose) {
   const route = {} as {
@@ -190,24 +37,3 @@ export function createMockedRoute(initialValue: RouteLocationNormalizedLoose) {
     },
   }
 }
-
-function compileSlot(template: string) {
-  const codegen = compile(template, {
-    mode: 'function',
-    hoistStatic: true,
-    prefixIdentifiers: true,
-  })
-
-  const render = new Function('Vue', codegen.code)(runtimeDom)
-
-  const ToRender = defineComponent({
-    render,
-    inheritAttrs: false,
-
-    setup(props, { attrs }) {
-      return { ...attrs }
-    },
-  })
-
-  return (propsData: any) => h(ToRender, { ...propsData })
-}
index 98647d64a40ad641b11d40a8c419c24368125dac..078190419389b2b65aecb765d379240514a19c33 100644 (file)
@@ -73,6 +73,7 @@
     "@vue/compiler-sfc": "^3.0.5",
     "@vue/devtools-api": "^6.0.0-beta.3",
     "@vue/server-renderer": "^3.0.5",
+    "@vue/test-utils": "^2.0.0-beta.13",
     "algoliasearch": "^4.8.3",
     "axios": "^0.21.1",
     "brotli": "^1.3.2",
index 5660e05a10af0b9ef5b2cdf9a5c7c77ff3b3c21b..ceaf0080bd396625cbc42d5252d8d87212fbbc03 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
   resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.0.5.tgz#c131d88bd6713cc4d93b3bb1372edb1983225ff0"
   integrity sha512-gYsNoGkWejBxNO6SNRjOh/xKeZ0H0V+TFzaPzODfBjkAIb0aQgBuixC1brandC/CDJy1wYPwSoYrXpvul7m6yw==
 
+"@vue/test-utils@^2.0.0-beta.13":
+  version "2.0.0-beta.13"
+  resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0-beta.13.tgz#482aa29f4e80a713e03e22b736d7465d56909e66"
+  integrity sha512-Au+yGMBPvrtcmPP6W4ielTbNJd3equxVOq1iL0DvpAZJwkGOrdBfFTomMhANODiBVyIEE8HMxhr7YIwDHWO36w==
+
 "@webassemblyjs/ast@1.9.1":
   version "1.9.1"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.1.tgz#76c6937716d68bf1484c15139f5ed30b9abc8bb4"