Skip to content

Commit

Permalink
test: migrate type tests from uvr
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Jun 17, 2024
1 parent c8a6f34 commit f7f78f0
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 123 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ jobs:
- run: pnpm install
- run: pnpm run lint
- run: pnpm run -r test:types
- run: pnpm run -r test:unit
- run: pnpm run -r build
- run: pnpm run -r build:dts
- run: pnpm run -r test:dts
- run: pnpm run -r test:unit

# e2e tests that that run locally
- run: pnpm run -r test:e2e:ci
Expand Down
47 changes: 47 additions & 0 deletions packages/router/__tests__/createRouter.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, it } from 'vitest'
import { createRouter, createWebHistory } from '../src'
import { defineComponent, h } from 'vue'

describe('createRouter', () => {
const component = defineComponent({})

const WithProps = defineComponent({
props: {
id: {
type: String,
required: true,
},
},
})

const Foo = defineComponent({
props: {
test: String,
},
setup() {
return {
title: 'homepage',
}
},
render() {
return h('div', `${this.title}: ${this.test}`)
},
})

it('works', () => {
createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component },
{ path: '/foo', component: Foo },
{ path: '/', component: WithProps },
],
parseQuery: search => ({}),
stringifyQuery: query => '',
strict: true,
end: true,
sensitive: true,
scrollBehavior(to, from, savedPosition) {},
})
})
})
82 changes: 82 additions & 0 deletions packages/router/__tests__/routeLocation.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { describe, it, expectTypeOf } from 'vitest'
import type {
RouteRecordName,
ParamValue,
ParamValueZeroOrMore,
RouteRecordInfo,
RouteLocationNormalizedTypedList,
} from '../src'

// TODO: could we move this to an .d.ts file that is only loaded for tests?
// https://github.com/microsoft/TypeScript/issues/15300
type RouteNamedMap = {
home: RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>
'/[other]': RouteRecordInfo<
'/[other]',
'/:other',
{ other: ParamValue<true> },
{ other: ParamValue<false> }
>
'/[name]': RouteRecordInfo<
'/[name]',
'/:name',
{ name: ParamValue<true> },
{ name: ParamValue<false> }
>
'/[...path]': RouteRecordInfo<
'/[...path]',
'/:path(.*)',
{ path: ParamValue<true> },
{ path: ParamValue<false> }
>
'/deep/nesting/works/[[files]]+': RouteRecordInfo<
'/deep/nesting/works/[[files]]+',
'/deep/nesting/works/:files*',
{ files?: ParamValueZeroOrMore<true> },
{ files?: ParamValueZeroOrMore<false> }
>
}

describe('Route Location types', () => {
it('RouteLocationNormalized', () => {
function withRoute(
fn: (
to: RouteLocationNormalizedTypedList<RouteNamedMap>[keyof RouteNamedMap]
) => void
): void
function withRoute<Name extends keyof RouteNamedMap>(
name: Name,
fn: (to: RouteLocationNormalizedTypedList<RouteNamedMap>[Name]) => void
): void
function withRoute<Name extends RouteRecordName>(...args: unknown[]) {}

withRoute('/[name]', to => {
expectTypeOf(to.params).toEqualTypeOf<{ name: string }>()
expectTypeOf(to.params).not.toEqualTypeOf<{ notExisting: string }>()
expectTypeOf(to.params).not.toEqualTypeOf<{ other: string }>()
})

withRoute('/[name]' as keyof RouteNamedMap, to => {
// @ts-expect-error: no all params have this
to.params.name
if (to.name === '/[name]') {
to.params.name
// @ts-expect-error: no param other
to.params.other
}
})

withRoute(to => {
// @ts-expect-error: not all params object have a name
to.params.name
// @ts-expect-error: no route named like that
if (to.name === '') {
}
if (to.name === '/[name]') {
expectTypeOf(to.params).toEqualTypeOf<{ name: string }>()
// @ts-expect-error: no param other
to.params.other
}
})
})
})
5 changes: 2 additions & 3 deletions packages/router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@
"build:size": "pnpm run build && rollup -c size-checks/rollup.config.mjs",
"dev:e2e": "vite --config e2e/vite.config.mjs",
"test:types": "tsc --build tsconfig.json",
"test:dts": "tsc -p ./test-dts/tsconfig.json",
"test:unit": "vitest --coverage",
"test": "pnpm run test:types && pnpm run test:unit && pnpm run build && pnpm run build:dts && pnpm run test:e2e",
"test:unit": "vitest --coverage run",
"test": "pnpm run test:types && pnpm run build && pnpm run build:dts && pnpm run test:unit && pnpm run test:e2e",
"test:e2e": "pnpm run test:e2e:headless",
"test:e2e:headless": "node e2e/runner.mjs --env chrome-headless",
"test:e2e:native": "node e2e/runner.mjs --env chrome",
Expand Down
19 changes: 9 additions & 10 deletions packages/router/test-dts/components.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import {
RouterView,
createRouter,
createMemoryHistory,
expectError,
expectType,
} from './index'
import { expectTypeOf } from 'vitest'

let router = createRouter({
history: createMemoryHistory(),
Expand All @@ -20,13 +19,13 @@ expectError(<RouterLink />)
expectError(<RouterLink to="/" custom="text" />)
// @ts-expect-error: invalid prop
expectError(<RouterLink to="/" replace="text" />)
expectType<JSX.Element>(<RouterLink to="/foo" replace />)
expectType<JSX.Element>(<RouterLink to="/foo" />)
expectType<JSX.Element>(<RouterLink class="link" to="/foo" />)
expectType<JSX.Element>(<RouterLink to={{ path: '/foo' }} />)
expectType<JSX.Element>(<RouterLink to={{ path: '/foo' }} custom />)
expectTypeOf<JSX.Element>(<RouterLink to="/foo" replace />)
expectTypeOf<JSX.Element>(<RouterLink to="/foo" />)
expectTypeOf<JSX.Element>(<RouterLink class="link" to="/foo" />)
expectTypeOf<JSX.Element>(<RouterLink to={{ path: '/foo' }} />)
expectTypeOf<JSX.Element>(<RouterLink to={{ path: '/foo' }} custom />)

// RouterView
expectType<JSX.Element>(<RouterView class="view" />)
expectType<JSX.Element>(<RouterView name="foo" />)
expectType<JSX.Element>(<RouterView route={router.currentRoute.value} />)
expectTypeOf<JSX.Element>(<RouterView class="view" />)
expectTypeOf<JSX.Element>(<RouterView name="foo" />)
expectTypeOf<JSX.Element>(<RouterView route={router.currentRoute.value} />)
61 changes: 0 additions & 61 deletions packages/router/test-dts/createRouter.test-d.ts

This file was deleted.

5 changes: 0 additions & 5 deletions packages/router/test-dts/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
export * from '../dist/vue-router'
// export * from '../src'

export function describe(_name: string, _fn: () => void): void
export function expectType<T>(value: T): void
export function expectError<T>(value: T): void
export function expectAssignable<T, T2 extends T = T>(value: T2): void
7 changes: 4 additions & 3 deletions packages/router/test-dts/legacy.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Router, RouteLocationNormalizedLoaded, expectType } from './index'
import { expectTypeOf } from 'vitest'
import { Router, RouteLocationNormalizedLoaded } from './index'
import { defineComponent } from 'vue'

defineComponent({
methods: {
doStuff() {
expectType<Router>(this.$router)
expectType<RouteLocationNormalizedLoaded>(this.$route)
expectTypeOf<Router>(this.$router)
expectTypeOf<RouteLocationNormalizedLoaded>(this.$route)
},
},
})
68 changes: 38 additions & 30 deletions packages/router/test-dts/meta.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createRouter, createWebHistory, expectType } from './index'
import { createApp, defineComponent } from 'vue'
import { createRouter, createWebHistory } from './index'
import { defineComponent } from 'vue'
import { describe, it, expectTypeOf } from 'vitest'

const component = defineComponent({})

Expand All @@ -10,34 +11,41 @@ declare module './index' {
}
}

const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component,
meta: {
requiresAuth: true,
lol: true,
nested: {
foo: 'bar',
describe('RouteMeta', () => {
it('route creation', () => {
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component,
meta: {
requiresAuth: true,
lol: true,
nested: {
foo: 'bar',
},
},
},
},
},
{
path: '/foo',
component,
// @ts-expect-error
meta: {},
},
],
})
{
path: '/foo',
component,
// @ts-expect-error
meta: {},
},
],
})
})

router.beforeEach(to => {
expectType<{ requiresAuth?: Boolean; nested: { foo: string } }>(to.meta)
expectType<unknown>(to.meta.lol)
if (to.meta.nested.foo == 'foo' || to.meta.lol) return false
it('route location in guards', () => {
const router = createRouter({
history: createWebHistory(),
routes: [],
})
router.beforeEach(to => {
expectTypeOf<{ requiresAuth?: Boolean; nested: { foo: string } }>(to.meta)
expectTypeOf<unknown>(to.meta.lol)
if (to.meta.nested.foo == 'foo' || to.meta.lol) return false
})
})
})

const app = createApp({})
app.use(router)
12 changes: 6 additions & 6 deletions packages/router/test-dts/navigationGuards.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expectTypeOf } from 'vitest'
import {
createRouter,
createWebHistory,
expectType,
isNavigationFailure,
NavigationFailure,
NavigationFailureType,
Expand Down Expand Up @@ -45,13 +45,13 @@ router.beforeEach((to, from, next) => {
})

router.afterEach((to, from, failure) => {
expectType<NavigationFailure | undefined | void>(failure)
expectTypeOf<NavigationFailure | undefined | void>(failure)
if (isNavigationFailure(failure)) {
expectType<RouteLocationNormalized>(failure.from)
expectType<RouteLocationRaw>(failure.to)
expectTypeOf<RouteLocationNormalized>(failure.from)
expectTypeOf<RouteLocationRaw>(failure.to)
}
if (isNavigationFailure(failure, NavigationFailureType.cancelled)) {
expectType<RouteLocationNormalized>(failure.from)
expectType<RouteLocationRaw>(failure.to)
expectTypeOf<RouteLocationNormalized>(failure.from)
expectTypeOf<RouteLocationRaw>(failure.to)
}
})
Loading

0 comments on commit f7f78f0

Please sign in to comment.