Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add tests for dev server and proxy #644

Merged
merged 11 commits into from
Dec 8, 2022
13 changes: 13 additions & 0 deletions test/presets/nitro-dev.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { describe } from 'vitest'
import { startDevServer, setupTest, testNitro } from '../tests'

describe('nitro:preset:nitro-dev', async () => {
const ctx = await setupTest('nitro-dev')
testNitro(ctx, async () => {
await startDevServer(ctx)
return async ({ url }) => {
const res = await ctx.fetch(url)
return res
}
})
})
41 changes: 32 additions & 9 deletions test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,38 @@ import { expect, it, afterAll } from 'vitest'
import { fileURLToPath } from 'mlly'
import { joinURL } from 'ufo'
import * as _nitro from '../src'
import type { Nitro } from '../src'
import { createDevServer, Nitro } from '../src'

const { createNitro, build, prepare, copyPublicAssets, prerender } = (_nitro as any as { default: typeof _nitro }).default || _nitro

interface Context {
preset: string
nitro?: Nitro,
nitro?: Nitro
rootDir: string
outDir: string
devDir: string
fetch: (url: string) => Promise<any>
server?: Listener
isDev: boolean
}

export async function setupTest (preset) {
export async function setupTest (preset: string) {
const fixtureDir = fileURLToPath(new URL('./fixture', import.meta.url).href)

const ctx: Context = {
preset,
isDev: preset === 'nitro-dev',
rootDir: fixtureDir,
outDir: resolve(fixtureDir, '.output', preset),
devDir: resolve(fixtureDir, '.nitro', 'dev'),
fetch: url => fetch(joinURL(ctx.server!.url, url.slice(1)), { redirect: 'manual' })
}

const nitro = ctx.nitro = await createNitro({
preset: ctx.preset,
dev: ctx.isDev,
rootDir: ctx.rootDir,
serveStatic: preset !== 'cloudflare' && preset !== 'vercel-edge',
serveStatic: preset !== 'cloudflare' && preset !== 'vercel-edge' && !ctx.isDev,
output: { dir: ctx.outDir },
routeRules: {
'/rules/headers': { headers: { 'cache-control': 's-maxage=60' } },
Expand All @@ -46,10 +51,13 @@ export async function setupTest (preset) {
'/rules/nested/override': { redirect: { to: '/other' } }
}
})
await prepare(nitro)
await copyPublicAssets(nitro)
await prerender(nitro)
await build(nitro)

if (!ctx.isDev) {
await prepare(nitro)
await copyPublicAssets(nitro)
await prerender(nitro)
await build(nitro)
}

afterAll(async () => {
if (ctx.server) {
Expand All @@ -63,11 +71,21 @@ export async function setupTest (preset) {
return ctx
}

export async function startServer (ctx, handle) {
export async function startServer (ctx: Context, handle) {
ctx.server = await listen(handle)
console.log('>', ctx.server!.url)
}

export async function startDevServer (ctx: Context) {
const devServer = createDevServer(ctx.nitro)
ctx.server = await devServer.listen({})
await prepare(ctx.nitro)
await build(ctx.nitro)
// TODO: How to await that dev server is ready?!
await new Promise(resolve => setTimeout(resolve, 1000))
danielroe marked this conversation as resolved.
Show resolved Hide resolved
pi0 marked this conversation as resolved.
Show resolved Hide resolved
console.log('>', ctx.server!.url)
}

type TestHandlerResult = { data: any, status: number, headers: Record<string, string> }
type TestHandler = (options: any) => Promise<TestHandlerResult | Response>

Expand Down Expand Up @@ -162,6 +180,11 @@ export function testNitro (ctx: Context, getHandler: () => TestHandler | Promise
expect(data.hasEnv).toBe(true)
})

it('returns correct status for devProxy', async () => {
const { status } = await callHandler({ url: '/proxy/example' })
expect(status).toBe(ctx.isDev ? 200 : 404)
})

if (ctx.nitro!.options.serveStatic) {
it('serve static asset /favicon.ico', async () => {
const { status, headers } = await callHandler({ url: '/favicon.ico' })
Expand Down