mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
test: refactor type tests into a separate fixture (#21007)
This commit is contained in:
parent
397c54c9db
commit
fd30cc1e89
@ -21,7 +21,9 @@
|
||||
"test:fixtures:payload": "TEST_PAYLOAD=js pnpm test:fixtures",
|
||||
"test:fixtures:dev": "TEST_ENV=dev pnpm test:fixtures",
|
||||
"test:fixtures:webpack": "TEST_BUILDER=webpack pnpm test:fixtures",
|
||||
"test:types": "nuxi prepare test/fixtures/basic && cd test/fixtures/basic && npx vue-tsc --noEmit",
|
||||
"test:types": "pnpm test:types:basic && pnpm test:types:minimal",
|
||||
"test:types:basic": "nuxi prepare test/fixtures/basic-types && cd test/fixtures/basic-types && npx vue-tsc --noEmit",
|
||||
"test:types:minimal": "nuxi prepare test/fixtures/minimal-types && cd test/fixtures/minimal-types && npx vue-tsc --noEmit",
|
||||
"test:unit": "vitest run --dir packages",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
|
@ -913,12 +913,37 @@ importers:
|
||||
specifier: latest
|
||||
version: 4.2.1(vue@3.3.4)
|
||||
|
||||
test/fixtures/basic-types:
|
||||
dependencies:
|
||||
nuxt:
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/nuxt
|
||||
devDependencies:
|
||||
ofetch:
|
||||
specifier: latest
|
||||
version: 1.0.1
|
||||
unplugin:
|
||||
specifier: latest
|
||||
version: 1.3.1
|
||||
vitest:
|
||||
specifier: latest
|
||||
version: 0.31.1(playwright@1.34.0)
|
||||
vue-router:
|
||||
specifier: latest
|
||||
version: 4.2.1(vue@3.3.4)
|
||||
|
||||
test/fixtures/minimal:
|
||||
dependencies:
|
||||
nuxt:
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/nuxt
|
||||
|
||||
test/fixtures/minimal-types:
|
||||
dependencies:
|
||||
nuxt:
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/nuxt
|
||||
|
||||
test/fixtures/runtime-compiler:
|
||||
dependencies:
|
||||
nuxt:
|
||||
|
1
test/fixtures/basic-types/.gitignore
vendored
Normal file
1
test/fixtures/basic-types/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
!extends/node_modules
|
6
test/fixtures/basic-types/app.config.ts
vendored
Normal file
6
test/fixtures/basic-types/app.config.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export default defineAppConfig({
|
||||
userConfig: 123,
|
||||
nested: {
|
||||
val: 2
|
||||
}
|
||||
})
|
28
test/fixtures/basic-types/components/WithTypes.vue
vendored
Normal file
28
test/fixtures/basic-types/components/WithTypes.vue
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
aProp: Number
|
||||
})
|
||||
defineSlots<{
|
||||
fallback: { id: string }
|
||||
}>()
|
||||
defineExpose<{
|
||||
_exposedValue: boolean
|
||||
}>()
|
||||
|
||||
const _exposedValue = 42
|
||||
|
||||
const emit = defineEmits<{
|
||||
'some-event': [id: string]
|
||||
}>()
|
||||
emit('some-event', '42')
|
||||
// @ts-expect-error an invalid argument
|
||||
emit('some-event', 42)
|
||||
// @ts-expect-error an unknown event
|
||||
emit('unknown-event', 42)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- -->
|
||||
</div>
|
||||
</template>
|
3
test/fixtures/basic-types/extends/bar/app.config.ts
vendored
Normal file
3
test/fixtures/basic-types/extends/bar/app.config.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
fromLayer: true
|
||||
}
|
5
test/fixtures/basic-types/extends/bar/index.d.ts
vendored
Normal file
5
test/fixtures/basic-types/extends/bar/index.d.ts
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
declare module 'bing' {
|
||||
interface BingInterface {
|
||||
foo: 'bar'
|
||||
}
|
||||
}
|
6
test/fixtures/basic-types/extends/bar/layouts/override.vue
vendored
Normal file
6
test/fixtures/basic-types/extends/bar/layouts/override.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>Extended layout from bar</div>
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</template>
|
3
test/fixtures/basic-types/extends/bar/middleware/override.ts
vendored
Normal file
3
test/fixtures/basic-types/extends/bar/middleware/override.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
to.meta.override = 'Injected by extended middleware from bar'
|
||||
})
|
1
test/fixtures/basic-types/extends/bar/nuxt.config.ts
vendored
Normal file
1
test/fixtures/basic-types/extends/bar/nuxt.config.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default defineNuxtConfig({})
|
14
test/fixtures/basic-types/extends/bar/pages/override.vue
vendored
Normal file
14
test/fixtures/basic-types/extends/bar/pages/override.vue
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
layout: 'override',
|
||||
middleware: 'override'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>Extended page from bar</div>
|
||||
<div>Middleware | override: {{ $route.meta.override }}</div>
|
||||
<ExtendsOverride />
|
||||
</div>
|
||||
</template>
|
6
test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue
generated
vendored
Normal file
6
test/fixtures/basic-types/extends/node_modules/foo/layouts/default.vue
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>Extended layout from foo</div>
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/layouts/override.vue
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>This layout should be overriden by bar</div>
|
||||
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/foo.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
to.meta.foo = 'Injected by extended middleware from foo'
|
||||
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/middleware/override.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
to.meta.override = 'This middleware should be overriden by bar'
|
||||
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/nuxt.config.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { defineNuxtConfig } from 'nuxt/config'
|
||||
|
||||
export default defineNuxtConfig({})
|
19
test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue
generated
vendored
Normal file
19
test/fixtures/basic-types/extends/node_modules/foo/pages/foo.vue
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<script setup>
|
||||
import { test } from '~/alias/test'
|
||||
definePageMeta({
|
||||
middleware: 'foo'
|
||||
})
|
||||
|
||||
const foo = useExtendsFoo()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>{{ test }}</div>
|
||||
<div>Extended page from foo</div>
|
||||
<div>Middleware | foo: {{ $route.meta.foo }}</div>
|
||||
<div>Composable | useExtendsFoo: {{ foo }}</div>
|
||||
<div>Plugin | foo: {{ $foo() }}</div>
|
||||
<ExtendsFoo />
|
||||
</div>
|
||||
</template>
|
3
test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/pages/override.vue
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>This page should be overriden by bar</div>
|
||||
</template>
|
7
test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts
generated
vendored
Normal file
7
test/fixtures/basic-types/extends/node_modules/foo/plugins/foo.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export default defineNuxtPlugin(() => {
|
||||
return {
|
||||
provide: {
|
||||
foo: () => 'String generated from foo plugin!'
|
||||
}
|
||||
}
|
||||
})
|
3
test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts
generated
vendored
Normal file
3
test/fixtures/basic-types/extends/node_modules/foo/server/api/foo.ts
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { eventHandler } from 'h3'
|
||||
|
||||
export default eventHandler(() => 'foo')
|
0
test/fixtures/basic-types/layouts/PascalCase.ts
vendored
Normal file
0
test/fixtures/basic-types/layouts/PascalCase.ts
vendored
Normal file
6
test/fixtures/basic-types/layouts/custom.vue
vendored
Normal file
6
test/fixtures/basic-types/layouts/custom.vue
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
Custom Layout:
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
7
test/fixtures/basic-types/middleware/global.global.ts
vendored
Normal file
7
test/fixtures/basic-types/middleware/global.global.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
if ('abort' in to.query) {
|
||||
return abortNavigation({
|
||||
statusCode: 401
|
||||
})
|
||||
}
|
||||
})
|
3
test/fixtures/basic-types/middleware/named.ts
vendored
Normal file
3
test/fixtures/basic-types/middleware/named.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
to.meta.auth = 'Injected by injectAuth middleware'
|
||||
})
|
15
test/fixtures/basic-types/modules/auto-registered/index.ts
vendored
Normal file
15
test/fixtures/basic-types/modules/auto-registered/index.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { addServerHandler, createResolver, defineNuxtModule } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
meta: {
|
||||
name: 'auto-registered-module'
|
||||
},
|
||||
setup () {
|
||||
const resolver = createResolver(import.meta.url)
|
||||
|
||||
addServerHandler({
|
||||
handler: resolver.resolve('./runtime/handler'),
|
||||
route: '/auto-registered-module'
|
||||
})
|
||||
}
|
||||
})
|
1
test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts
vendored
Normal file
1
test/fixtures/basic-types/modules/auto-registered/runtime/handler.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default defineEventHandler(() => 'handler added by auto-registered module')
|
23
test/fixtures/basic-types/modules/example.ts
vendored
Normal file
23
test/fixtures/basic-types/modules/example.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
defaults: {
|
||||
enabled: true,
|
||||
typeTest: (value: boolean) => typeof value === 'boolean'
|
||||
},
|
||||
meta: {
|
||||
name: 'my-module',
|
||||
configKey: 'sampleModule'
|
||||
},
|
||||
setup () {
|
||||
const resolver = createResolver(import.meta.url)
|
||||
|
||||
addPlugin(resolver.resolve('./runtime/plugin'))
|
||||
useNuxt().hook('app:resolve', (app) => {
|
||||
app.middleware.push({
|
||||
name: 'unctx-test',
|
||||
path: resolver.resolve('./runtime/middleware')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
19
test/fixtures/basic-types/modules/page-extend.ts
vendored
Normal file
19
test/fixtures/basic-types/modules/page-extend.ts
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
import { createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
meta: {
|
||||
name: 'page-extend'
|
||||
},
|
||||
setup () {
|
||||
const nuxt = useNuxt()
|
||||
const resolver = createResolver(import.meta.url)
|
||||
|
||||
nuxt.hook('pages:extend', (pages) => {
|
||||
pages.push({
|
||||
name: 'page-extend',
|
||||
path: '/page-extend',
|
||||
file: resolver.resolve('./runtime/page.vue')
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
4
test/fixtures/basic-types/modules/runtime/middleware.ts
vendored
Normal file
4
test/fixtures/basic-types/modules/runtime/middleware.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export default defineNuxtRouteMiddleware(async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1))
|
||||
useNuxtApp()
|
||||
})
|
17
test/fixtures/basic-types/modules/runtime/page.vue
vendored
Normal file
17
test/fixtures/basic-types/modules/runtime/page.vue
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { setResponseHeader } from 'h3'
|
||||
|
||||
definePageMeta({
|
||||
value: 'added in pages:extend'
|
||||
})
|
||||
|
||||
if (process.server) {
|
||||
setResponseHeader(useRequestEvent(), 'x-extend', useRoute().meta.value as string)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
added in pages:extend
|
||||
</div>
|
||||
</template>
|
4
test/fixtures/basic-types/modules/runtime/plugin.ts
vendored
Normal file
4
test/fixtures/basic-types/modules/runtime/plugin.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export default defineNuxtPlugin(async () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1))
|
||||
useNuxtApp()
|
||||
})
|
7
test/fixtures/basic-types/modules/test/index.ts
vendored
Normal file
7
test/fixtures/basic-types/modules/test/index.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineNuxtModule } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
meta: {
|
||||
name: 'test'
|
||||
}
|
||||
})
|
76
test/fixtures/basic-types/nuxt.config.ts
vendored
Normal file
76
test/fixtures/basic-types/nuxt.config.ts
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
typedPages: true
|
||||
},
|
||||
typescript: {
|
||||
strict: true,
|
||||
tsConfig: {
|
||||
compilerOptions: {
|
||||
moduleResolution: process.env.MODULE_RESOLUTION
|
||||
}
|
||||
}
|
||||
},
|
||||
buildDir: process.env.NITRO_BUILD_DIR,
|
||||
builder: process.env.TEST_BUILDER as 'webpack' | 'vite' ?? 'vite',
|
||||
theme: './extends/bar',
|
||||
extends: [
|
||||
'./extends/node_modules/foo'
|
||||
],
|
||||
runtimeConfig: {
|
||||
baseURL: '',
|
||||
baseAPIToken: '',
|
||||
privateConfig: 'secret_key',
|
||||
public: {
|
||||
ids: [1, 2, 3],
|
||||
needsFallback: undefined,
|
||||
testConfig: 123
|
||||
}
|
||||
},
|
||||
appConfig: {
|
||||
fromNuxtConfig: true,
|
||||
nested: {
|
||||
val: 1
|
||||
}
|
||||
},
|
||||
modules: [
|
||||
'./modules/test',
|
||||
[
|
||||
'~/modules/example',
|
||||
{
|
||||
typeTest (val) {
|
||||
// @ts-expect-error module type defines val as boolean
|
||||
const b: string = val
|
||||
return !!b
|
||||
}
|
||||
}
|
||||
],
|
||||
function (_options, nuxt) {
|
||||
nuxt.hook('pages:extend', (pages) => {
|
||||
pages.push({
|
||||
name: 'internal-async-parent',
|
||||
path: '/internal-async-parent'
|
||||
})
|
||||
})
|
||||
}
|
||||
],
|
||||
telemetry: false, // for testing telemetry types - it is auto-disabled in tests
|
||||
hooks: {
|
||||
'schema:extend' (schemas) {
|
||||
schemas.push({
|
||||
appConfig: {
|
||||
someThing: {
|
||||
value: {
|
||||
$default: 'default',
|
||||
$schema: {
|
||||
tsType: 'string | false'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
'prepare:types' ({ tsConfig }) {
|
||||
tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*')
|
||||
}
|
||||
}
|
||||
})
|
16
test/fixtures/basic-types/package.json
vendored
Normal file
16
test/fixtures/basic-types/package.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "fixture-basic-types",
|
||||
"scripts": {
|
||||
"build": "nuxi build"
|
||||
},
|
||||
"dependencies": {
|
||||
"nuxt": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ofetch": "latest",
|
||||
"unplugin": "latest",
|
||||
"vitest": "latest",
|
||||
"vue-router": "latest"
|
||||
}
|
||||
}
|
5
test/fixtures/basic-types/pages/page.vue
vendored
Normal file
5
test/fixtures/basic-types/pages/page.vue
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- -->
|
||||
</div>
|
||||
</template>
|
5
test/fixtures/basic-types/pages/param/[id].vue
vendored
Normal file
5
test/fixtures/basic-types/pages/param/[id].vue
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- -->
|
||||
</div>
|
||||
</template>
|
7
test/fixtures/basic-types/plugins/injection.ts
vendored
Normal file
7
test/fixtures/basic-types/plugins/injection.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export default defineNuxtPlugin(() => {
|
||||
return {
|
||||
provide: {
|
||||
pluginInjection: () => ''
|
||||
}
|
||||
}
|
||||
})
|
1
test/fixtures/basic-types/server/api/hello.ts
vendored
Normal file
1
test/fixtures/basic-types/server/api/hello.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default defineEventHandler(() => 'Hello API')
|
4
test/fixtures/basic-types/server/api/hey/index.get.ts
vendored
Normal file
4
test/fixtures/basic-types/server/api/hey/index.get.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export default defineEventHandler(() => ({
|
||||
foo: 'bar',
|
||||
baz: 'qux'
|
||||
}))
|
3
test/fixtures/basic-types/server/api/hey/index.post.ts
vendored
Normal file
3
test/fixtures/basic-types/server/api/hey/index.post.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export default defineEventHandler(() => ({
|
||||
method: 'post' as const
|
||||
}))
|
4
test/fixtures/basic-types/server/api/union.ts
vendored
Normal file
4
test/fixtures/basic-types/server/api/union.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export default defineEventHandler(() => ({
|
||||
type: 'a',
|
||||
foo: 'bar'
|
||||
}) as { type: 'a', foo: string } | { type: 'b', baz: string })
|
3
test/fixtures/basic-types/server/tsconfig.json
vendored
Normal file
3
test/fixtures/basic-types/server/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../.nuxt/tsconfig.server.json"
|
||||
}
|
3
test/fixtures/basic-types/tsconfig.json
vendored
Normal file
3
test/fixtures/basic-types/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
@ -7,7 +7,7 @@ import type { AppConfig, RuntimeValue } from 'nuxt/schema'
|
||||
import { defineNuxtConfig } from 'nuxt/config'
|
||||
import { callWithNuxt, isVue3 } from '#app'
|
||||
import type { NavigateToOptions } from '#app/composables/router'
|
||||
import { NuxtLink, NuxtPage } from '#components'
|
||||
import { NuxtLink, NuxtPage, WithTypes } from '#components'
|
||||
import { useRouter } from '#imports'
|
||||
|
||||
interface TestResponse { message: string }
|
||||
@ -15,6 +15,10 @@ interface TestResponse { message: string }
|
||||
describe('API routes', () => {
|
||||
it('generates types for routes', () => {
|
||||
expectTypeOf($fetch('/api/hello')).toEqualTypeOf<Promise<string>>()
|
||||
// registered in extends
|
||||
expectTypeOf($fetch('/api/foo')).toEqualTypeOf<Promise<string>>()
|
||||
// registered in module
|
||||
expectTypeOf($fetch('/auto-registered-module')).toEqualTypeOf<Promise<string>>()
|
||||
expectTypeOf($fetch('/api/hey')).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
||||
expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
|
||||
expectTypeOf($fetch('/api/hey', { method: 'post' })).toEqualTypeOf<Promise<{ method: 'post' }>>()
|
||||
@ -90,11 +94,14 @@ describe('aliases', () => {
|
||||
|
||||
describe('middleware', () => {
|
||||
it('recognizes named middleware', () => {
|
||||
definePageMeta({ middleware: 'inject-auth' })
|
||||
definePageMeta({ middleware: 'named' })
|
||||
// provided by layer
|
||||
definePageMeta({ middleware: 'override' })
|
||||
definePageMeta({ middleware: 'foo' })
|
||||
// @ts-expect-error ignore global middleware
|
||||
definePageMeta({ middleware: 'redirect' })
|
||||
definePageMeta({ middleware: 'global' })
|
||||
// @ts-expect-error Invalid middleware
|
||||
definePageMeta({ middleware: 'invalid-middleware' })
|
||||
definePageMeta({ middleware: 'nonexistent' })
|
||||
})
|
||||
it('handles adding middleware', () => {
|
||||
addRouteMiddleware('example', (to, from) => {
|
||||
@ -117,14 +124,14 @@ describe('typed router integration', () => {
|
||||
// @ts-expect-error this named route does not exist
|
||||
router.push({ name: 'some-thing' })
|
||||
// this one does
|
||||
router.push({ name: 'fixed-keyed-child-parent' })
|
||||
router.push({ name: 'page' })
|
||||
// @ts-expect-error this is an invalid param
|
||||
router.push({ name: 'random-id', params: { bob: 23 } })
|
||||
router.push({ name: 'random-id', params: { id: 4 } })
|
||||
router.push({ name: 'param-id', params: { bob: 23 } })
|
||||
router.push({ name: 'param-id', params: { id: 4 } })
|
||||
})
|
||||
|
||||
it('allows typing useRoute', () => {
|
||||
const route = useRoute('random-id')
|
||||
const route = useRoute('param-id')
|
||||
// @ts-expect-error this param does not exist
|
||||
const _invalid = route.params.something
|
||||
// this param does
|
||||
@ -135,36 +142,40 @@ describe('typed router integration', () => {
|
||||
// @ts-expect-error this named route does not exist
|
||||
navigateTo({ name: 'some-thing' })
|
||||
// this one does
|
||||
navigateTo({ name: 'fixed-keyed-child-parent' })
|
||||
navigateTo({ name: 'page' })
|
||||
// @ts-expect-error this is an invalid param
|
||||
navigateTo({ name: 'random-id', params: { bob: 23 } })
|
||||
navigateTo({ name: 'random-id', params: { id: 4 } })
|
||||
navigateTo({ name: 'param-id', params: { bob: 23 } })
|
||||
navigateTo({ name: 'param-id', params: { id: 4 } })
|
||||
})
|
||||
|
||||
it('allows typing middleware', () => {
|
||||
defineNuxtRouteMiddleware((to) => {
|
||||
expectTypeOf(to.name).not.toBeAny()
|
||||
// @ts-expect-error this route does not exist
|
||||
expectTypeOf(to.name === 'bob').toMatchTypeOf<boolean>()
|
||||
expectTypeOf(to.name === 'assets').toMatchTypeOf<boolean>()
|
||||
expectTypeOf(to.name === 'bob').toEqualTypeOf<boolean>()
|
||||
expectTypeOf(to.name === 'page').toEqualTypeOf<boolean>()
|
||||
})
|
||||
})
|
||||
|
||||
it('respects pages:extend augmentation', () => {
|
||||
// added via pages:extend
|
||||
expectTypeOf(useRoute().name === 'internal-async-parent').toMatchTypeOf<boolean>()
|
||||
expectTypeOf(useRoute().name === 'internal-async-parent').toEqualTypeOf<boolean>()
|
||||
// @ts-expect-error this route does not exist
|
||||
expectTypeOf(useRoute().name === 'invalid').toMatchTypeOf<boolean>()
|
||||
expectTypeOf(useRoute().name === 'invalid').toEqualTypeOf<boolean>()
|
||||
})
|
||||
|
||||
it('respects pages added via layer', () => {
|
||||
expectTypeOf(useRoute().name === 'override').toEqualTypeOf<boolean>()
|
||||
})
|
||||
|
||||
it('allows typing NuxtLink', () => {
|
||||
// @ts-expect-error this named route does not exist
|
||||
h(NuxtLink, { to: { name: 'some-thing' } })
|
||||
// this one does
|
||||
h(NuxtLink, { to: { name: 'fixed-keyed-child-parent' } })
|
||||
h(NuxtLink, { to: { name: 'page' } })
|
||||
// @ts-expect-error this is an invalid param
|
||||
h(NuxtLink, { to: { name: 'random-id', params: { bob: 23 } } })
|
||||
h(NuxtLink, { to: { name: 'random-id', params: { id: 4 } } })
|
||||
h(NuxtLink, { to: { name: 'param-id', params: { bob: 23 } } })
|
||||
h(NuxtLink, { to: { name: 'param-id', params: { id: 4 } } })
|
||||
})
|
||||
})
|
||||
|
||||
@ -172,6 +183,7 @@ describe('layouts', () => {
|
||||
it('recognizes named layouts', () => {
|
||||
definePageMeta({ layout: 'custom' })
|
||||
definePageMeta({ layout: 'pascal-case' })
|
||||
definePageMeta({ layout: 'override' })
|
||||
// @ts-expect-error Invalid layout
|
||||
definePageMeta({ layout: 'invalid-layout' })
|
||||
})
|
||||
@ -189,7 +201,8 @@ describe('modules', () => {
|
||||
|
||||
describe('nuxtApp', () => {
|
||||
it('types injections provided by plugins', () => {
|
||||
expectTypeOf(useNuxtApp().$asyncPlugin).toEqualTypeOf<() => string>()
|
||||
expectTypeOf(useNuxtApp().$pluginInjection).toEqualTypeOf<() => ''>()
|
||||
expectTypeOf(useNuxtApp().$foo).toEqualTypeOf<() => 'String generated from foo plugin!'>()
|
||||
expectTypeOf(useNuxtApp().$router).toEqualTypeOf<Router>()
|
||||
})
|
||||
it('marks unknown injections as unknown', () => {
|
||||
@ -264,6 +277,13 @@ describe('components', () => {
|
||||
it('includes types for NuxtPage', () => {
|
||||
expectTypeOf(NuxtPage).not.toBeAny()
|
||||
})
|
||||
it('includes types for other components', () => {
|
||||
h(WithTypes)
|
||||
// @ts-expect-error wrong prop type for this component
|
||||
h(WithTypes, { aProp: '40' })
|
||||
|
||||
// TODO: assert typed slots, exposed, generics, etc.
|
||||
})
|
||||
})
|
||||
|
||||
describe('composables', () => {
|
4
test/fixtures/basic/modules/example.ts
vendored
4
test/fixtures/basic/modules/example.ts
vendored
@ -1,10 +1,6 @@
|
||||
import { addPlugin, createResolver, defineNuxtModule, useNuxt } from 'nuxt/kit'
|
||||
|
||||
export default defineNuxtModule({
|
||||
defaults: {
|
||||
enabled: true,
|
||||
typeTest: (value: boolean) => typeof value === 'boolean'
|
||||
},
|
||||
meta: {
|
||||
name: 'my-module',
|
||||
configKey: 'sampleModule'
|
||||
|
38
test/fixtures/basic/nuxt.config.ts
vendored
38
test/fixtures/basic/nuxt.config.ts
vendored
@ -11,14 +11,6 @@ declare module 'nitropack' {
|
||||
}
|
||||
|
||||
export default defineNuxtConfig({
|
||||
typescript: {
|
||||
strict: true,
|
||||
tsConfig: {
|
||||
compilerOptions: {
|
||||
moduleResolution: process.env.MODULE_RESOLUTION
|
||||
}
|
||||
}
|
||||
},
|
||||
app: {
|
||||
pageTransition: true,
|
||||
layoutTransition: true,
|
||||
@ -70,27 +62,14 @@ export default defineNuxtConfig({
|
||||
]
|
||||
},
|
||||
runtimeConfig: {
|
||||
baseURL: '',
|
||||
baseAPIToken: '',
|
||||
privateConfig: 'secret_key',
|
||||
public: {
|
||||
ids: [1, 2, 3],
|
||||
needsFallback: undefined,
|
||||
testConfig: 123
|
||||
}
|
||||
},
|
||||
modules: [
|
||||
'./modules/test',
|
||||
[
|
||||
'~/modules/example',
|
||||
{
|
||||
typeTest (val) {
|
||||
// @ts-expect-error module type defines val as boolean
|
||||
const b: string = val
|
||||
return !!b
|
||||
}
|
||||
}
|
||||
],
|
||||
function (_, nuxt) {
|
||||
if (typeof nuxt.options.builder === 'string' && nuxt.options.builder.includes('webpack')) { return }
|
||||
|
||||
@ -143,23 +122,6 @@ export default defineNuxtConfig({
|
||||
},
|
||||
telemetry: false, // for testing telemetry types - it is auto-disabled in tests
|
||||
hooks: {
|
||||
'schema:extend' (schemas) {
|
||||
schemas.push({
|
||||
appConfig: {
|
||||
someThing: {
|
||||
value: {
|
||||
$default: 'default',
|
||||
$schema: {
|
||||
tsType: 'string | false'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
'prepare:types' ({ tsConfig }) {
|
||||
tsConfig.include = tsConfig.include!.filter(i => i !== '../../../../**/*')
|
||||
},
|
||||
'modules:done' () {
|
||||
addComponent({
|
||||
name: 'CustomComponent',
|
||||
|
3
test/fixtures/minimal-types/app.vue
vendored
Normal file
3
test/fixtures/minimal-types/app.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Hello World!</div>
|
||||
</template>
|
1
test/fixtures/minimal-types/nuxt.config.ts
vendored
Normal file
1
test/fixtures/minimal-types/nuxt.config.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default defineNuxtConfig({})
|
10
test/fixtures/minimal-types/package.json
vendored
Normal file
10
test/fixtures/minimal-types/package.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "fixture-minimal-types",
|
||||
"scripts": {
|
||||
"build": "nuxi build"
|
||||
},
|
||||
"dependencies": {
|
||||
"nuxt": "workspace:*"
|
||||
}
|
||||
}
|
3
test/fixtures/minimal-types/tsconfig.json
vendored
Normal file
3
test/fixtures/minimal-types/tsconfig.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
48
test/fixtures/minimal-types/types.ts
vendored
Normal file
48
test/fixtures/minimal-types/types.ts
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import { describe, expectTypeOf, it } from 'vitest'
|
||||
|
||||
describe('routing utilities', () => {
|
||||
it('allows using route composables', () => {
|
||||
const router = useRouter()
|
||||
router.push('/test')
|
||||
|
||||
expectTypeOf(useRouter()).not.toBeAny()
|
||||
expectTypeOf(useRoute()).not.toBeAny()
|
||||
|
||||
navigateTo('/thing')
|
||||
})
|
||||
})
|
||||
|
||||
describe('auto-imports', () => {
|
||||
it('defineNuxtConfig', () => {
|
||||
defineNuxtConfig({
|
||||
modules: [],
|
||||
// @ts-expect-error Should show error on unknown properties
|
||||
unknownProp: ''
|
||||
})
|
||||
})
|
||||
it('core composables', () => {
|
||||
ref()
|
||||
useHead({
|
||||
script: [],
|
||||
// @ts-expect-error Should show error on unknown properties
|
||||
unknown: []
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('config typings', () => {
|
||||
it('runtimeConfig', () => {
|
||||
expectTypeOf(useRuntimeConfig()).toMatchTypeOf<{
|
||||
app: {
|
||||
baseURL: string
|
||||
buildAssetsDir: string
|
||||
cdnURL: string
|
||||
}
|
||||
public: Record<string, any>
|
||||
}>()
|
||||
})
|
||||
|
||||
it('appConfig', () => {
|
||||
expectTypeOf(useAppConfig()).toEqualTypeOf<{ [key: string]: unknown }>()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user