Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
feat: mock <RouterLink>
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Dec 9, 2022
1 parent b8240fb commit b1e61fa
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 51 deletions.
2 changes: 1 addition & 1 deletion playground/app.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<LazySomeComponent />
<!-- TODO: <NuxtPage /> -->
<!-- TODO: <NuxtLink to="/test">Test link</NuxtLink> -->
<NuxtLink to="/test">Test link</NuxtLink>
</template>

<script setup>
Expand Down
6 changes: 6 additions & 0 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<template>
<div>Index page</div>
</template>

<script setup>
definePageMeta({
value: 'set in index',
})
</script>
14 changes: 8 additions & 6 deletions playground/tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ describe('client-side nuxt features', () => {
expect(app.$router).toBeDefined()
})

it('works with route composables', async () => {
expect(useRoute().matched[0].meta).toMatchInlineSnapshot('{}')
it('defaults to index page', async () => {
expect(useRoute().matched[0].meta).toMatchInlineSnapshot(`
{
"value": "set in index",
}
`)
expect(useRoute().fullPath).toMatchInlineSnapshot('"/"')
// TODO:
// await useRouter().push('/test')
// expect(useRoute().fullPath).toMatchInlineSnapshot('"/test"')
// TODO: should it be possible to push to other routes?
})
})

Expand All @@ -40,7 +42,7 @@ describe('test utils', () => {
expect(component.html()).toMatchInlineSnapshot(`
"<div>This is an auto-imported component</div>
<!-- TODO: <NuxtPage /> -->
<!-- TODO: <NuxtLink to=\\"/test\\">Test link</NuxtLink> -->"
<a href=\\"/test\\">Test link</a>"
`)
})

Expand Down
7 changes: 6 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ async function getViteConfig (rootDir = process.cwd()) {
const nuxt = await loadNuxt({
cwd: rootDir,
dev: false,
overrides: { ssr: false },
overrides: {
ssr: false,
app: {
rootId: 'nuxt-test'
},
},
})
return new Promise<InlineConfig>((resolve, reject) => {
nuxt.hook('vite:extendConfig', config => {
Expand Down
21 changes: 21 additions & 0 deletions src/runtime/components/RouterLink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const RouterLink = defineComponent({
functional: true,
props: {
to: String,
custom: Boolean,
replace: Boolean,
// Not implemented
activeClass: String,
exactActiveClass: String,
ariaCurrentValue: String
},
setup: (props, { slots }) => {
const navigate = () => {}
return () => {
const route = props.to ? useRouter().resolve(props.to) : {}
return props.custom
? slots.default?.({ href: props.to, navigate, route })
: h('a', { href: props.to, onClick: (e: MouseEvent) => { e.preventDefault(); return navigate() } }, slots)
}
}
})
41 changes: 8 additions & 33 deletions src/runtime/mount.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { mount, VueWrapper } from '@vue/test-utils'
import { h, DefineComponent, Suspense } from 'vue'

import { RouterLink } from './components/RouterLink'

// @ts-expect-error virtual file
import NuxtRoot from '#build/root-component.mjs'

Expand All @@ -9,39 +11,12 @@ export async function mountSuspended<T extends DefineComponent<any, any, any, an
const vm = mount({
setup: NuxtRoot.setup,
render: () => h(Suspense, { onResolve: () => resolve(vm as any) }, { default: () => h(component) })
}, {
global: {
components: {
RouterLink
}
}
})
})
}


export async function mountSuspendedWithRoute<T extends DefineComponent<any, any, any, any>> (component: T) {
return new Promise<VueWrapper<InstanceType<T>>>(async resolve => {
// const vueApp = createApp({
// setup: NuxtRoot.setup,
// render: () => h(Suspense, { onResolve: () => resolve(vueApp as any) }, { default: () => h(component) })
// })

// const nuxt = createNuxtApp({ vueApp })

// try {
// await applyPlugins(nuxt, plugins)
// } catch (err) {
// await nuxt.callHook('app:error', err)
// nuxt.payload.error = (nuxt.payload.error || err) as any
// }

// try {
// await nuxt.hooks.callHook('app:created', vueApp)
// await nuxt.hooks.callHook('app:beforeMount', vueApp)
// const app = document.createElement('div')
// document.body.appendChild(app)
// app.id = 'something'
// vueApp.mount('#something')
// await nuxt.hooks.callHook('app:mounted', vueApp)
// await nextTick()
// } catch (err) {
// await nuxt.callHook('app:error', err)
// nuxt.payload.error = (nuxt.payload.error || err) as any
// }
})
}
19 changes: 9 additions & 10 deletions src/vitest-environment-nuxt/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import type { Environment } from 'vitest'
import { builtinEnvironments, populateGlobal } from 'vitest/environments'
import { Window, GlobalWindow } from 'happy-dom'
import { createFetch } from 'ohmyfetch'
import { App, createApp, defineEventHandler, toNodeListener } from 'h3'
import { App, createApp, toNodeListener } from 'h3'
import {
createCall,
createFetch as createLocalFetch,
} from 'unenv/runtime/fetch/index'
// @ts-expect-error TODO: add subpath types
import * as viteEnvironments from 'vitest/environments'
const { populateGlobal } = viteEnvironments as typeof import('vitest/dist/environments')

export default <Environment> {
name: 'nuxt',
async setup () {
const win = new (GlobalWindow || Window)() as any as (Window & {
__app: App
__registry: Set<string>
__NUXT__: any
$fetch: any
fetch: any
})

// @ts-expect-error undeclared property on window
win.__NUXT__ = {
serverRendered: false,
config: {
Expand All @@ -30,16 +32,13 @@ export default <Environment> {
}

const app = win.document.createElement('div')
app.id = 'nuxt-test'
win.document.body.appendChild(app)

// Workaround for happy-dom bug
const { querySelector } = win.document
app.id = 'nuxt'
function qsWrapper (selectors) {
if (selectors === '#__nuxt') selectors = '#nuxt'
return querySelector(selectors)
// @ts-expect-error
win.IntersectionObserver = win.IntersectionObserver || class IntersectionObserver {
observe () {}
}
win.document.querySelector = qsWrapper

const h3App = createApp()

Expand Down

0 comments on commit b1e61fa

Please sign in to comment.