[cli] Convert DevServer "Unit" suite tests to "Dev" suite tests (#7845)

The `DevServer` class as it's currently implement is not really suitable for unit testing, since it calls `process.exit()` when shutting down the server. This causes Jest to exit prematurely, and prevents tests after these one from running. This was in fact hiding some failing tests. So these tests were ported over to be "Dev" suite tests which spawn a child process of `vc dev` rather than running them in-process, so that the `process.exit()` doesn't exit Jest.
This commit is contained in:
Nathan Rajlich
2022-05-23 16:38:02 -07:00
committed by GitHub
parent a5a990995c
commit 75ea68d445
42 changed files with 388 additions and 444 deletions

View File

@@ -98,6 +98,12 @@ export default async function dev(
]);
}
// This is just for tests - can be removed once project settings
// are respected locally in `.vercel/project.json`
if (process.env.VERCEL_DEV_COMMAND) {
devCommand = process.env.VERCEL_DEV_COMMAND;
}
const devServer = new DevServer(cwd, {
output,
devCommand,

View File

@@ -0,0 +1 @@
export default () => <div>hello, this is the frontend</div>;

View File

@@ -1,6 +1,5 @@
{
"version": 2,
"name": "now-dev-headers",
"builds": [
{ "src": "index.js", "use": "@vercel/node" },
{ "src": "foo.txt", "use": "@vercel/static" }

View File

@@ -1,6 +1,5 @@
{
"version": 2,
"name": "now-dev-query-test",
"builds": [{ "src": "index.js", "use": "@vercel/node" }],
"routes": [
{

View File

@@ -1,5 +1,5 @@
{
"name": "now-dev-static-build-routing",
"name": "vc-dev-static-build-routing",
"private": true,
"scripts": {
"now-dev": "serve -l $PORT src",

View File

@@ -1,6 +1,9 @@
import os from 'os';
import url from 'url';
import fs from 'fs-extra';
import { join } from 'path';
import listen from 'async-listen';
import { createServer } from 'http';
const {
exec,
@@ -8,8 +11,374 @@ const {
fixture,
testFixture,
testFixtureStdio,
validateResponseHeaders,
} = require('./utils.js');
test('[vercel dev] should support request body', async () => {
const dir = fixture('node-request-body');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const body = { hello: 'world' };
// Test that `req.body` works in dev
let res = await fetch(`http://localhost:${port}/api/req-body`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(body),
});
validateResponseHeaders(res);
expect(await res.json()).toMatchObject(body);
// Test that `req` "data" events work in dev
res = await fetch(`http://localhost:${port}/api/data-events`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(body),
});
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should maintain query when invoking serverless function', async () => {
const dir = fixture('node-query-invoke');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/something?url-param=a`);
validateResponseHeaders(res);
const text = await res.text();
const parsed = url.parse(text, true);
expect(parsed.pathname).toEqual('/something');
expect(parsed.query['url-param']).toEqual('a');
expect(parsed.query['route-param']).toEqual('b');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should maintain query when proxy passing', async () => {
const dir = fixture('query-proxy');
const { dev, port, readyResolver } = await testFixture(dir);
const dest = createServer((req, res) => {
res.end(req.url);
});
try {
await Promise.all([readyResolver, listen(dest, 0)]);
const destAddr = dest.address();
if (!destAddr || typeof destAddr === 'string') {
throw new Error('Unexpected HTTP address');
}
const res = await fetch(
`http://localhost:${port}/${destAddr.port}?url-param=a`
);
validateResponseHeaders(res);
const text = await res.text();
const parsed = url.parse(text, true);
expect(parsed.pathname).toEqual('/something');
expect(parsed.query['url-param']).toEqual('a');
expect(parsed.query['route-param']).toEqual('b');
} finally {
dest.close();
dev.kill('SIGTERM');
}
});
test('[vercel dev] should maintain query when dev server defines routes', async () => {
const dir = fixture('dev-server-query');
const { dev, port, readyResolver } = await testFixture(dir, {
env: {
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
},
});
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/test?url-param=a`);
validateResponseHeaders(res);
const text = await res.text();
// Hacky way of getting the page payload from the response
// HTML since we don't have a HTML parser handy.
const json = text
.match(/<pre>(.*)<\/pre>/)![1]
.replace('</pre>', '')
.replace('<!-- -->', '')
.replace(/&amp;/g, '&')
.replace(/&quot;/g, '"');
const parsed = JSON.parse(json);
const query = url.parse(parsed.url, true).query;
expect(query['url-param']).toEqual('a');
expect(query['route-param']).toEqual('b');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should allow `cache-control` to be overwritten', async () => {
const dir = fixture('headers');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(
`http://localhost:${port}/?name=cache-control&value=immutable`
);
expect(res.headers.get('cache-control')).toEqual('immutable');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should send `etag` header for static files', async () => {
const dir = fixture('headers');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/foo.txt`);
const expected = 'd263af8ab880c0b97eb6c5c125b5d44f9e5addd9';
expect(res.headers.get('etag')).toEqual(`"${expected}"`);
const body = await res.text();
expect(body.trim()).toEqual('hi');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should frontend dev server and routes', async () => {
const dir = fixture('dev-server-and-routes');
const { dev, port, readyResolver } = await testFixture(dir, {
env: {
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
},
});
try {
await readyResolver;
let podId: string;
let res = await fetch(`http://localhost:${port}/`);
validateResponseHeaders(res);
podId = res.headers.get('x-vercel-id')!.match(/:(\w+)-/)![1];
let body = await res.text();
expect(body.includes('hello, this is the frontend')).toBeTruthy();
res = await fetch(`http://localhost:${port}/api/users`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('users');
res = await fetch(`http://localhost:${port}/api/users/1`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('users/1');
res = await fetch(`http://localhost:${port}/api/welcome`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('hello and welcome');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support `@vercel/static` routing', async () => {
const dir = fixture('static-routes');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/`);
expect(res.status).toEqual(200);
const body = await res.text();
expect(body.trim()).toEqual('<body>Hello!</body>');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support `@vercel/static-build` routing', async () => {
const dir = fixture('static-build-routing');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/api/date`);
expect(res.status).toEqual(200);
const body = await res.text();
expect(body.startsWith('The current date:')).toBeTruthy();
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support directory listing', async () => {
const dir = fixture('directory-listing');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
// Get directory listing
let res = await fetch(`http://localhost:${port}/`);
let body = await res.text();
expect(res.status).toEqual(200);
expect(body.includes('Index of')).toBeTruthy();
// Get a file
res = await fetch(`http://localhost:${port}/file.txt`);
body = await res.text();
expect(res.status).toEqual(200);
expect(body.trim()).toEqual('Hello from file!');
// Invoke a lambda
res = await fetch(`http://localhost:${port}/lambda.js`);
body = await res.text();
expect(res.status).toEqual(200);
expect(body).toEqual('Hello from Lambda!');
// Trigger a 404
res = await fetch(`http://localhost:${port}/does-not-exist`);
expect(res.status).toEqual(404);
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should respond with 404 listing with Accept header support', async () => {
const dir = fixture('directory-listing');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
// HTML response
let res = await fetch(`http://localhost:${port}/does-not-exist`, {
headers: {
Accept: 'text/html',
},
});
expect(res.status).toEqual(404);
expect(res.headers.get('content-type')).toEqual('text/html; charset=utf-8');
let body = await res.text();
expect(body.startsWith('<!DOCTYPE html>')).toBeTruthy();
// JSON response
res = await fetch(`http://localhost:${port}/does-not-exist`, {
headers: {
Accept: 'application/json',
},
});
expect(res.status).toEqual(404);
expect(res.headers.get('content-type')).toEqual('application/json');
body = await res.text();
expect(body).toEqual(
'{"error":{"code":404,"message":"The page could not be found."}}\n'
);
// Plain text response
res = await fetch(`http://localhost:${port}/does-not-exist`);
expect(res.status).toEqual(404);
body = await res.text();
expect(res.headers.get('content-type')).toEqual(
'text/plain; charset=utf-8'
);
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support `public` directory with zero config', async () => {
const dir = fixture('api-with-public');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
let res = await fetch(`http://localhost:${port}/api/user`);
let body = await res.text();
expect(body).toEqual('hello:user');
res = await fetch(`http://localhost:${port}/`);
body = await res.text();
expect(body.startsWith('<h1>hello world</h1>')).toBeTruthy();
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support static files with zero config', async () => {
const dir = fixture('api-with-static');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
let res = await fetch(`http://localhost:${port}/api/user`);
let body = await res.text();
expect(body).toEqual('bye:user');
res = await fetch(`http://localhost:${port}/`);
body = await res.text();
expect(body.startsWith('<h1>goodbye world</h1>')).toBeTruthy();
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] should support custom 404 routes', async () => {
const dir = fixture('custom-404');
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
// Test custom 404 with static dest
let res = await fetch(`http://localhost:${port}/error.html`);
expect(res.status).toEqual(404);
let body = await res.text();
expect(body.trim()).toEqual('<div>Custom 404 page</div>');
// Test custom 404 with lambda dest
res = await fetch(`http://localhost:${port}/error.js`);
expect(res.status).toEqual(404);
body = await res.text();
expect(body).toEqual('Custom 404 Lambda\n');
// Test regular 404 still works
res = await fetch(`http://localhost:${port}/does-not-exist`);
expect(res.status).toEqual(404);
body = await res.text();
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
} finally {
dev.kill('SIGTERM');
}
});
test('[vercel dev] prints `npm install` errors', async () => {
const dir = fixture('runtime-not-installed');
const result = await exec(dir);

View File

@@ -96,10 +96,16 @@ function shouldSkip(name, versions) {
return false;
}
function validateResponseHeaders(res) {
function validateResponseHeaders(res, podId) {
if (res.status < 500) {
expect(res.headers.get('server')).toEqual('Vercel');
expect(res.headers.get('cache-control').length > 0).toBeTruthy();
expect(res.headers.get('x-vercel-id')).toBeTruthy();
expect(res.headers.get('cache-control').length > 0).toBeTruthy;
if (podId) {
expect(
res.headers.get('x-vercel-id').includes(`::${podId}-`)
).toBeTruthy();
}
}
}

View File

@@ -1 +0,0 @@
export default () => <div>hello, this is the frontend</div>

View File

@@ -1,3 +1,4 @@
import ms from 'ms';
import { join } from 'path';
import { remove } from 'fs-extra';
import { getWriteableDirectory } from '@vercel/build-utils';
@@ -9,6 +10,8 @@ import {
import vercelNextPkg from '@vercel/next/package.json';
import vercelNodePkg from '@vercel/node/package.json';
jest.setTimeout(ms('20 seconds'));
describe('importBuilders()', () => {
it('should import built-in Builders', async () => {
const specs = new Set(['@vercel/node', '@vercel/next']);

View File

@@ -1,438 +0,0 @@
import ms from 'ms';
import url from 'url';
import path from 'path';
import execa from 'execa';
import fs from 'fs-extra';
import fetch, { Response } from 'node-fetch';
import listen from 'async-listen';
import { createServer } from 'http';
import { client } from '../../../mocks/client';
import DevServer from '../../../../src/util/dev/server';
import { DevServerOptions } from '../../../../src/util/dev/types';
const IS_WINDOWS = process.platform === 'win32';
async function runNpmInstall(fixturePath: string) {
if (await fs.pathExists(path.join(fixturePath, 'package.json'))) {
return execa('yarn', ['install', '--network-timeout', '1000000'], {
cwd: fixturePath,
shell: true,
});
}
}
interface TestFixtureOptions extends Omit<DevServerOptions, 'output'> {
skip?: boolean;
}
const testFixture =
(
name: string,
fn: (server: DevServer) => Promise<void>,
options?: TestFixtureOptions
) =>
async () => {
if (options?.skip) {
console.log('Skipping this test for this platform.');
return;
}
let server: DevServer | undefined;
const fixturePath = path.join(__dirname, '../../fixtures/unit', name);
await runNpmInstall(fixturePath);
try {
server = new DevServer(fixturePath, {
...options,
output: client.output,
});
await server.start(0);
await fn(server);
} finally {
await server?.stop();
}
};
function validateResponseHeaders(res: Response, podId?: string) {
expect(res.headers.get('server')).toEqual('Vercel');
expect(res.headers.get('cache-control')!.length > 0).toBeTruthy();
expect(
/^dev1::(dev1::)?[0-9a-z]{5}-[1-9][0-9]+-[a-f0-9]{12}$/.test(
res.headers.get('x-vercel-id')!
)
).toBeTruthy();
if (podId) {
expect(
res.headers.get('x-vercel-id')!.startsWith(`dev1::${podId}`) ||
res.headers.get('x-vercel-id')!.startsWith(`dev1::dev1::${podId}`)
).toBeTruthy();
}
}
describe('DevServer', () => {
jest.setTimeout(ms('2m'));
it(
'should support request body',
testFixture('now-dev-request-body', async server => {
const body = { hello: 'world' };
// Test that `req.body` works in dev
let res = await fetch(`${server.address}/api/req-body`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(body),
});
validateResponseHeaders(res);
expect(await res.json()).toMatchObject(body);
// Test that `req` "data" events work in dev
res = await fetch(`${server.address}/api/data-events`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(body),
});
expect(await res.json()).toMatchObject(body);
})
);
it(
'should maintain query when invoking serverless function',
testFixture('now-dev-query-invoke', async server => {
const res = await fetch(`${server.address}/something?url-param=a`);
validateResponseHeaders(res);
const text = await res.text();
const parsed = url.parse(text, true);
expect(parsed.pathname).toEqual('/something');
expect(parsed.query['url-param']).toEqual('a');
expect(parsed.query['route-param']).toEqual('b');
})
);
it(
'should maintain query when proxy passing',
testFixture('now-dev-query-proxy', async server => {
const dest = createServer((req, res) => {
res.end(req.url);
});
await listen(dest, 0);
const addr = dest.address();
if (!addr || typeof addr === 'string') {
throw new Error('Unexpected HTTP address');
}
const { port } = addr;
try {
const res = await fetch(`${server.address}/${port}?url-param=a`);
validateResponseHeaders(res);
const text = await res.text();
const parsed = url.parse(text, true);
expect(parsed.pathname).toEqual('/something');
expect(parsed.query['url-param']).toEqual('a');
expect(parsed.query['route-param']).toEqual('b');
} finally {
dest.close();
}
})
);
it(
'should maintain query when builder defines routes',
testFixture(
'now-dev-next',
async server => {
const res = await fetch(`${server.address}/test?url-param=a`);
validateResponseHeaders(res);
const text = await res.text();
// Hacky way of getting the page payload from the response
// HTML since we don't have a HTML parser handy.
const json = text
.match(/<pre>(.*)<\/pre>/)![1]
.replace('</pre>', '')
.replace('<!-- -->', '')
.replace(/&amp;/g, '&')
.replace(/&quot;/g, '"');
const parsed = JSON.parse(json);
const query = url.parse(parsed.url, true).query;
expect(query['url-param']).toEqual('a');
expect(query['route-param']).toEqual('b');
},
{
devCommand: 'next dev --port $PORT',
}
)
);
it(
'should allow `cache-control` to be overwritten',
testFixture('now-dev-headers', async server => {
const res = await fetch(
`${server.address}/?name=cache-control&value=immutable`
);
expect(res.headers.get('cache-control')).toEqual('immutable');
})
);
it(
'should send `etag` header for static files',
testFixture('now-dev-headers', async server => {
const res = await fetch(`${server.address}/foo.txt`);
const expected = IS_WINDOWS
? '9dc423ab77c2e0446cd355256efff2ea1be27cbf'
: 'd263af8ab880c0b97eb6c5c125b5d44f9e5addd9';
expect(res.headers.get('etag')).toEqual(`"${expected}"`);
const body = await res.text();
expect(body.trim()).toEqual('hi');
})
);
it(
'should support default builds and routes',
testFixture(
'now-dev-default-builds-and-routes',
async server => {
let podId: string;
let res = await fetch(`${server.address}/`);
validateResponseHeaders(res);
podId = res.headers.get('x-vercel-id')!.match(/:(\w+)-/)![1];
let body = await res.text();
expect(body.includes('hello, this is the frontend')).toBeTruthy();
res = await fetch(`${server.address}/api/users`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('users');
res = await fetch(`${server.address}/api/users/1`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('users/1');
res = await fetch(`${server.address}/api/welcome`);
validateResponseHeaders(res, podId);
body = await res.text();
expect(body).toEqual('hello and welcome');
},
{
devCommand: 'next dev --port $PORT',
}
)
);
it(
'should support `@vercel/static` routing',
testFixture('now-dev-static-routes', async server => {
const res = await fetch(`${server.address}/`);
expect(res.status).toEqual(200);
const body = await res.text();
expect(body.trim()).toEqual('<body>Hello!</body>');
})
);
it(
'should support `@vercel/static-build` routing',
testFixture(
'now-dev-static-build-routing',
async server => {
const res = await fetch(`${server.address}/api/date`);
expect(res.status).toEqual(200);
const body = await res.text();
expect(body.startsWith('The current date:')).toBeTruthy();
},
{
// This test is currently failing on Windows, so skip for now:
// > Creating initial build
// $ serve -l $PORT src
// 'serve' is not recognized as an internal or external command,
// https://github.com/vercel/vercel/pull/6638/checks?check_run_id=3449662836
skip: IS_WINDOWS,
}
)
);
it(
'should support directory listing',
testFixture('now-dev-directory-listing', async server => {
// Get directory listing
let res = await fetch(`${server.address}/`);
let body = await res.text();
expect(res.status).toEqual(200);
expect(body.includes('Index of')).toBeTruthy();
// Get a file
res = await fetch(`${server.address}/file.txt`);
body = await res.text();
expect(res.status).toEqual(200);
expect(body.trim()).toEqual('Hello from file!');
// Invoke a lambda
res = await fetch(`${server.address}/lambda.js`);
body = await res.text();
expect(res.status).toEqual(200);
expect(body).toEqual('Hello from Lambda!');
// Trigger a 404
res = await fetch(`${server.address}/does-not-exist`);
expect(res.status).toEqual(404);
})
);
it(
'should support `public` directory with zero config',
testFixture('now-dev-api-with-public', async server => {
let res = await fetch(`${server.address}/api/user`);
let body = await res.text();
expect(body).toEqual('hello:user');
res = await fetch(`${server.address}/`);
body = await res.text();
expect(body.startsWith('<h1>hello world</h1>')).toBeTruthy();
})
);
it(
'should support static files with zero config',
testFixture('now-dev-api-with-static', async server => {
let res = await fetch(`${server.address}/api/user`);
let body = await res.text();
expect(body).toEqual('bye:user');
res = await fetch(`${server.address}/`);
body = await res.text();
expect(body.startsWith('<h1>goodbye world</h1>')).toBeTruthy();
})
);
it(
'should respond with 404 listing with Accept header support',
testFixture('now-dev-directory-listing', async server => {
// HTML response
let res = await fetch(`${server.address}/does-not-exist`, {
headers: {
Accept: 'text/html',
},
});
expect(res.status).toEqual(404);
expect(res.headers.get('content-type')).toEqual(
'text/html; charset=utf-8'
);
let body = await res.text();
expect(body.startsWith('<!DOCTYPE html>')).toBeTruthy();
// JSON response
res = await fetch(`${server.address}/does-not-exist`, {
headers: {
Accept: 'application/json',
},
});
expect(res.status).toEqual(404);
expect(res.headers.get('content-type')).toEqual('application/json');
body = await res.text();
expect(body).toEqual(
'{"error":{"code":404,"message":"The page could not be found."}}\n'
);
// Plain text response
res = await fetch(`${server.address}/does-not-exist`);
expect(res.status).toEqual(404);
body = await res.text();
expect(res.headers.get('content-type')).toEqual(
'text/plain; charset=utf-8'
);
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
})
);
it(
'should support custom 404 routes',
testFixture('now-dev-custom-404', async server => {
// Test custom 404 with static dest
let res = await fetch(`${server.address}/error.html`);
expect(res.status).toEqual(404);
let body = await res.text();
expect(body.trim()).toEqual('<div>Custom 404 page</div>');
// Test custom 404 with lambda dest
res = await fetch(`${server.address}/error.js`);
expect(res.status).toEqual(404);
body = await res.text();
expect(body).toEqual('Custom 404 Lambda\n');
// Test regular 404 still works
res = await fetch(`${server.address}/does-not-exist`);
expect(res.status).toEqual(404);
body = await res.text();
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
})
);
/*
it(
'should support edge middleware',
testFixture('edge-middleware', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.json();
expect(body).toEqual(
JSON.parse(
fs.readFileSync(
path.join(
__dirname,
'../../fixtures/unit/edge-middleware/response.json'
),
'utf8'
)
)
);
})
);
it(
'should work with middleware written in typescript',
testFixture('edge-middleware-ts', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual('response');
})
);
it(
'should render an error page when the middleware throws',
testFixture('edge-middleware-error', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual(
'A server error has occurred\n\nEDGE_FUNCTION_INVOCATION_FAILED\n'
);
})
);
it(
'should render an error page when the middleware returns not a Response',
testFixture('edge-middleware-invalid-response', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual(
'A server error has occurred\n\nEDGE_FUNCTION_INVOCATION_FAILED\n'
);
})
);
it(
'should run middleware in strict mode',
testFixture('edge-middleware-strict', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual('is strict mode? yes');
})
);
*/
});