Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-bags-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@web/dev-server-core': major
---

Replace `chai` with `node:assert/strict` in the published `test-helpers` module. The `fetchText` helper now throws `node:assert`'s `AssertionError` instead of `chai`'s on non-200 responses.
5 changes: 3 additions & 2 deletions packages/dev-server-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
"start:event-stream": "node demo/event-stream/start-server.js",
"start:http2": "node demo/http2/start-server.js",
"start:import-asset": "node demo/import-asset/start-server.js",
"test": "mocha \"test/**/*.test.{ts,js,mjs,cjs}\" --require ts-node/register --exit --reporter dot",
"test:watch": "mocha \"test/**/*.test.{ts,js,mjs,cjs}\" --require ts-node/register --watch --watch-files src,test"
"test": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"",
"test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"",
"test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\""
},
"files": [
".self-signed-dev-server-ssl.cert",
Expand Down
4 changes: 2 additions & 2 deletions packages/dev-server-core/src/test-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import portfinder from 'portfinder';
import { expect } from 'chai';
import assert from 'node:assert/strict';
import { green, red, yellow } from 'nanocolors';

import { DevServer } from './server/DevServer.js';
Expand Down Expand Up @@ -63,7 +63,7 @@ export const timeout = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms
export async function fetchText(url: string, init?: RequestInit) {
const response = await fetch(url, init);

expect(response.status).to.equal(200);
assert.equal(response.status, 200);
return response.text();
}

Expand Down
6 changes: 3 additions & 3 deletions packages/dev-server-core/test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import {
fetchText,
expectIncludes,
virtualFilesPlugin,
} from '../src/test-helpers.js';
import { DevServerCoreConfig } from '../src/server/DevServerCoreConfig.js';
} from '../dist/test-helpers.js';
import type { DevServerCoreConfig } from '../dist/server/DevServerCoreConfig.js';

export function createTestServer(config: Partial<DevServerCoreConfig> = {}) {
return originalCreateTestServer({
rootDir: path.resolve(__dirname, 'fixtures', 'basic'),
rootDir: path.resolve(import.meta.dirname, 'fixtures', 'basic'),
...config,
});
}
Expand Down
25 changes: 13 additions & 12 deletions packages/dev-server-core/test/middleware/basePathMiddleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { expect } from 'chai';
import assert from 'node:assert/strict';
import { describe, it, beforeEach, afterEach } from 'node:test';

import { DevServer } from '../../src/server/DevServer.js';
import { createTestServer } from '../helpers.js';
import type { DevServer } from '../../dist/server/DevServer.js';
import { createTestServer } from '../helpers.ts';

describe('base path middleware', () => {
describe('without a trailing /', () => {
Expand All @@ -19,20 +20,20 @@ describe('base path middleware', () => {
const response = await fetch(`${host}/foo/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});

it('can request without base path', async () => {
const response = await fetch(`${host}/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});
});

context('with a trailing /', () => {
describe('with a trailing /', () => {
let host: string;
let server: DevServer;
beforeEach(async () => {
Expand All @@ -47,16 +48,16 @@ describe('base path middleware', () => {
const response = await fetch(`${host}/foo/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});

it('can request without base path', async () => {
const response = await fetch(`${host}/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { expect } from 'chai';
import assert from 'node:assert/strict';
import { describe, it, beforeEach, afterEach } from 'node:test';
import path from 'path';
import fs from 'fs';
import { nanoid } from 'nanoid';

import { createTestServer, timeout } from '../helpers.js';
import { DevServer } from '../../src/server/DevServer.js';
import { createTestServer, timeout } from '../helpers.ts';
import type { DevServer } from '../../dist/server/DevServer.js';

const fixtureDir = path.resolve(__dirname, '..', 'fixtures', 'basic');
const fixtureDir = path.resolve(import.meta.dirname, '..', 'fixtures', 'basic');
const testFileAName = '/cached-file-a.js';
const testFileBName = '/cached-file-b.js';
const testFileAPath = path.join(fixtureDir, testFileAName);
Expand All @@ -24,7 +25,7 @@ describe('etag cache middleware', () => {
server.stop();
});

context('', () => {
describe('cached file a', () => {
beforeEach(() => {
fs.writeFileSync(testFileAPath, '// this file is cached', 'utf-8');
});
Expand All @@ -37,21 +38,21 @@ describe('etag cache middleware', () => {
const initialResponse = await fetch(`${host}${testFileAName}`);
const etag = initialResponse.headers.get('etag')!;

expect(initialResponse.status).to.equal(200);
expect(await initialResponse.text()).to.equal('// this file is cached');
assert.equal(initialResponse.status, 200);
assert.equal(await initialResponse.text(), '// this file is cached');

expect(etag).to.be.a('string');
assert.equal(typeof etag, 'string');

const cachedResponse = await fetch(`${host}${testFileAName}`, {
headers: { 'If-None-Match': etag, 'Cache-Control': 'max-age=3600' },
});

expect(cachedResponse.status).to.equal(304);
expect(await cachedResponse.text()).to.equal('');
assert.equal(cachedResponse.status, 304);
assert.equal(await cachedResponse.text(), '');
});
});

context('', () => {
describe('cached file b', () => {
beforeEach(() => {
fs.writeFileSync(testFileBPath, '// this file is cached', 'utf-8');
});
Expand All @@ -66,9 +67,9 @@ describe('etag cache middleware', () => {
const initialResponse = await fetch(`${host}${testFileBName}`);
const etag = initialResponse.headers.get('etag');

expect(initialResponse.status).to.equal(200);
expect(await initialResponse.text()).to.equal('// this file is cached');
expect(etag).to.be.a('string');
assert.equal(initialResponse.status, 200);
assert.equal(await initialResponse.text(), '// this file is cached');
assert.equal(typeof etag, 'string');

await timeout(10);
const fileContent = `// the cache is busted${nanoid()}`;
Expand All @@ -78,8 +79,8 @@ describe('etag cache middleware', () => {
const headers = { headers: { 'if-none-match': etag } as Record<string, string> };
const cachedResponse = await fetch(`${host}${testFileBName}`, headers);

expect(cachedResponse.status).to.equal(200);
expect(await cachedResponse.text()).to.equal(fileContent);
assert.equal(cachedResponse.status, 200);
assert.equal(await cachedResponse.text(), fileContent);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { expect } from 'chai';
import assert from 'node:assert/strict';
import { describe, it, beforeEach, afterEach } from 'node:test';
import path from 'path';

import { createTestServer } from '../helpers.js';
import { DevServer } from '../../src/server/DevServer.js';
import { createTestServer } from '../helpers.ts';
import type { DevServer } from '../../dist/server/DevServer.js';

describe('history api fallback middleware', () => {
describe('index in root', () => {
Expand All @@ -11,7 +12,7 @@ describe('history api fallback middleware', () => {

beforeEach(async () => {
({ host, server } = await createTestServer({
appIndex: path.resolve(__dirname, '..', 'fixtures', 'basic', 'index.html'),
appIndex: path.resolve(import.meta.dirname, '..', 'fixtures', 'basic', 'index.html'),
}));
});

Expand All @@ -23,41 +24,41 @@ describe('history api fallback middleware', () => {
const response = await fetch(`${host}/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});

it('returns the fallback index.html for non-file requests', async () => {
const response = await fetch(`${host}/foo`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});

it('returns the fallback index.html for file requests with multiple segments', async () => {
const response = await fetch(`${host}/foo/bar/baz`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});

it('does not return index.html for file requests', async () => {
const response = await fetch(`${host}/src/hello-world.txt`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('Hello world!');
expect(responseText).to.not.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('Hello world!'));
assert.ok(!responseText.includes('<title>My app</title>'));
});

it('does return index.html for requests that have url parameters with . characters (issue 1059)', async () => {
const response = await fetch(`${host}/text-files/foo/bar/?baz=open.wc`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app</title>'));
});
});

Expand All @@ -67,7 +68,7 @@ describe('history api fallback middleware', () => {

beforeEach(async () => {
({ host, server } = await createTestServer({
appIndex: path.resolve(__dirname, '..', 'fixtures', 'basic', 'src', 'index.html'),
appIndex: path.resolve(import.meta.dirname, '..', 'fixtures', 'basic', 'src', 'index.html'),
}));
});

Expand All @@ -79,40 +80,40 @@ describe('history api fallback middleware', () => {
const response = await fetch(`${host}/src/index.html`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app 2</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app 2</title>'));
});

it('returns the fallback index.html for non-file requests', async () => {
const response = await fetch(`${host}/src/foo`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app 2</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app 2</title>'));
});

it('returns the fallback index.html for file requests with multiple segments', async () => {
const response = await fetch(`${host}/src/foo/bar/baz`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app 2</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app 2</title>'));
});

it('does not return the index.html for requests outside the index root', async () => {
const response = await fetch(`${host}/foo`);
const responseText = await response.text();

expect(response.status).to.equal(404);
expect(responseText).to.not.include('<title>My app 2</title>');
assert.equal(response.status, 404);
assert.ok(!responseText.includes('<title>My app 2</title>'));
});

it('does return index.html for requests that have url parameters with . characters (issue 1059)', async () => {
const response = await fetch(`${host}/src/foo/bar/?baz=open.wc`);
const responseText = await response.text();

expect(response.status).to.equal(200);
expect(responseText).to.include('<title>My app 2</title>');
assert.equal(response.status, 200);
assert.ok(responseText.includes('<title>My app 2</title>'));
});
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { expect } from 'chai';
import { Context } from 'koa';
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import type { Context } from 'koa';

import { createTestServer } from '../helpers.js';
import { createTestServer } from '../helpers.ts';

describe('plugin-file-parsed middleware', () => {
it('is called after other plugin hooks', async () => {
Expand Down Expand Up @@ -44,11 +45,11 @@ describe('plugin-file-parsed middleware', () => {
try {
const response = await fetch(`${host}/foo.js`);

expect(response.status).to.equal(200);
expect(response.headers.get('content-type')).to.include('application/javascript');
expect(order[order.length - 1]).to.equal('fileParsed');
expect(context).to.exist;
expect(context!.path).to.equal('/foo.js');
assert.equal(response.status, 200);
assert.ok(response.headers.get('content-type')?.includes('application/javascript'));
assert.equal(order[order.length - 1], 'fileParsed');
assert.ok(context);
assert.equal(context!.path, '/foo.js');
} finally {
server.stop();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect } from 'chai';
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';

import { createTestServer } from '../helpers.js';
import { createTestServer } from '../helpers.ts';

describe('plugin-mime-type middleware', () => {
it('can set the mime type of a file with a string', async () => {
Expand All @@ -20,8 +21,8 @@ describe('plugin-mime-type middleware', () => {
try {
const response = await fetch(`${host}/src/hello-world.txt`);

expect(response.status).to.equal(200);
expect(response.headers.get('content-type')).to.include('application/javascript');
assert.equal(response.status, 200);
assert.ok(response.headers.get('content-type')?.includes('application/javascript'));
} finally {
server.stop();
}
Expand All @@ -44,8 +45,8 @@ describe('plugin-mime-type middleware', () => {
try {
const response = await fetch(`${host}/src/hello-world.txt`);

expect(response.status).to.equal(200);
expect(response.headers.get('content-type')).to.include('application/javascript');
assert.equal(response.status, 200);
assert.ok(response.headers.get('content-type')?.includes('application/javascript'));
} finally {
server.stop();
}
Expand Down
Loading
Loading