diff --git a/cli.js b/cli.js index d3603576..c2349154 100755 --- a/cli.js +++ b/cli.js @@ -180,7 +180,7 @@ sade2 .option('--sw', 'Path to a script to be loaded in a service worker.') .option( '--assets', - 'Folder with assets to be served by the http server. (default process.cwd())' + 'One or more folders with assets to be served by the http server. (default process.cwd() will always be included)' ) .option('--cwd', 'Current directory.', defaultOptions.cwd) .option( @@ -217,6 +217,7 @@ sade2 * * @type {import('./src/types.js').RunnerOptions} */ + const options = merge(config ? config.config : {}, { input: input ? [input, ...opts._] : undefined, testFiles: [], diff --git a/mocks/assets/a/a.json b/mocks/assets/a/a.json new file mode 100644 index 00000000..10c30dbc --- /dev/null +++ b/mocks/assets/a/a.json @@ -0,0 +1 @@ +{ "a": 1 } diff --git a/mocks/assets/b/b.txt b/mocks/assets/b/b.txt new file mode 100644 index 00000000..95d09f2b --- /dev/null +++ b/mocks/assets/b/b.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/mocks/assets/test.a.js b/mocks/assets/test.a.js new file mode 100644 index 00000000..9deb1b88 --- /dev/null +++ b/mocks/assets/test.a.js @@ -0,0 +1,27 @@ +/* eslint-disable no-undef */ +// eslint-disable-next-line strict +const { is } = require('uvu/assert') + +describe('assets', () => { + it('can fetch a and package.json', async () => { + // assets from cwd is available + is( + await fetch(new URL('package.json', import.meta.url)).then( + (res) => res.status + ), + 200 + ) + + // assets from a + is( + await fetch(new URL('a.json', import.meta.url)).then((res) => res.status), + 200 + ) + + // assets from b + is( + await fetch(new URL('b.txt', import.meta.url)).then((res) => res.status), + 404 + ) + }) +}) diff --git a/mocks/assets/test.ab.js b/mocks/assets/test.ab.js new file mode 100644 index 00000000..01109653 --- /dev/null +++ b/mocks/assets/test.ab.js @@ -0,0 +1,27 @@ +/* eslint-disable no-undef */ +// eslint-disable-next-line strict +const { is } = require('uvu/assert') + +describe('assets', () => { + it('can fetch a, b and package.json', async () => { + // assets from cwd is available + is( + await fetch(new URL('package.json', import.meta.url)).then( + (res) => res.status + ), + 200 + ) + + // assets from a + is( + await fetch(new URL('a.json', import.meta.url)).then((res) => res.status), + 200 + ) + + // assets from b + is( + await fetch(new URL('b.txt', import.meta.url)).then((res) => res.status), + 200 + ) + }) +}) diff --git a/src/node/runner.js b/src/node/runner.js index 731d4795..3d1c8f40 100644 --- a/src/node/runner.js +++ b/src/node/runner.js @@ -28,7 +28,7 @@ const merge = mergeOptions.bind({ ignoreUndefined: true }) */ const defaultOptions = { cwd: process.cwd(), - assets: '', + assets: undefined, browser: 'chromium', debug: false, mode: 'main', // worker diff --git a/src/types.d.ts b/src/types.d.ts index 2872acc5..4de7a813 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -16,7 +16,7 @@ export interface RunnerOptions { mode: 'main' | 'worker' | 'node' incognito: boolean extension: boolean - assets: string + assets?: string[] before?: string sw?: string cov: boolean @@ -56,7 +56,7 @@ export interface CliOptions { watch?: boolean before?: string sw?: string - assets: string + assets?: string[] cwd: string extensions: string config?: string diff --git a/src/utils/index.js b/src/utils/index.js index 5f8663bf..52f2c02d 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -31,7 +31,7 @@ const merge = mergeOptions.bind({ */ export const defaultOptions = { cwd: process.cwd(), - assets: '', + assets: undefined, browser: 'chromium', debug: false, mode: 'main', // worker @@ -592,13 +592,21 @@ function getPort(port = 3000, host = '127.0.0.1') { * * @param {string} dir - Runner directory * @param {string} cwd - Current working directory - * @param {string} assets - Assets directory + * @param {string[]| undefined} assets - Assets directories * @returns {Promise<{ url: string; server: import('http').Server }>} */ export async function createPolka(dir, cwd, assets) { const host = '127.0.0.1' const port = await getPort(0, host) const url = `http://${host}:${port}/` + if (typeof assets === 'string') { + assets = [assets] + } else if (assets === undefined || assets === null) { + assets = [] + } + if (!assets.includes(cwd)) { + assets.push(cwd) + } return new Promise((resolve, reject) => { const { server } = polka() .use( @@ -618,22 +626,24 @@ export async function createPolka(dir, cwd, assets) { ) .use( // @ts-ignore - sirv(path.join(cwd, assets), { - dev: true, - setHeaders: ( - /** @type {{ setHeader: (arg0: string, arg1: string) => void; }} */ rsp, - /** @type {string} */ pathname - ) => { - // workaround for https://github.com/lukeed/sirv/issues/158 - we - // can't unset the `Content-Encoding` header because sirv sets it - // after this function is invoked and will only set it if it's not - // already set, so we need to set it to a garbage value that will be - // ignored by browsers - if (pathname.endsWith('.gz')) { - rsp.setHeader('Content-Encoding', 'unsupported-encoding') - } - }, - }) + ...assets.map((dir) => + sirv(dir, { + dev: true, + setHeaders: ( + /** @type {{ setHeader: (arg0: string, arg1: string) => void; }} */ rsp, + /** @type {string} */ pathname + ) => { + // workaround for https://github.com/lukeed/sirv/issues/158 - we + // can't unset the `Content-Encoding` header because sirv sets it + // after this function is invoked and will only set it if it's not + // already set, so we need to set it to a garbage value that will be + // ignored by browsers + if (pathname.endsWith('.gz')) { + rsp.setHeader('Content-Encoding', 'unsupported-encoding') + } + }, + }) + ) ) .listen(port, host, (/** @type {Error} */ err) => { if (err) { diff --git a/test.js b/test.js index c58a5b06..6ebc7917 100644 --- a/test.js +++ b/test.js @@ -310,6 +310,36 @@ describe('uvu', () => { }) }) +describe('assets', () => { + it('1 asset', async () => { + const proc = await execa('./cli.js', [ + 'mocks/assets/test.a.js', + '--runner', + 'mocha', + '--assets', + './mocks/assets/a', + ]) + + is(proc.exitCode, 0, 'exit code') + ok(proc.stdout.includes('passing'), 'process stdout') + }) + + it('2 assets', async () => { + const proc = await execa('./cli.js', [ + 'mocks/assets/test.ab.js', + '--runner', + 'mocha', + '--assets', + './mocks/assets/a', + '--assets', + './mocks/assets/b', + ]) + + is(proc.exitCode, 0, 'exit code') + ok(proc.stdout.includes('passing'), 'process stdout') + }) +}) + describe.skip('benchmark', function () { it('benchmark', async () => { const proc = await execa('./cli.js', [