mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Use real filesystem for unit testing (#12172)
This commit is contained in:
parent
5ab2d980aa
commit
64bb796c0f
38 changed files with 578 additions and 940 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -21,7 +21,8 @@ package-lock.json
|
||||||
|
|
||||||
packages/astro/src/**/*.prebuilt.ts
|
packages/astro/src/**/*.prebuilt.ts
|
||||||
packages/astro/src/**/*.prebuilt-dev.ts
|
packages/astro/src/**/*.prebuilt-dev.ts
|
||||||
!packages/astro/vendor/vite/dist
|
packages/astro/test/units/_temp-fixtures/*
|
||||||
|
!packages/astro/test/units/_temp-fixtures/package.json
|
||||||
packages/integrations/**/.netlify/
|
packages/integrations/**/.netlify/
|
||||||
|
|
||||||
# exclude IntelliJ/WebStorm stuff
|
# exclude IntelliJ/WebStorm stuff
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"**/dist/**",
|
"**/dist/**",
|
||||||
"**/smoke/**",
|
"**/smoke/**",
|
||||||
"**/fixtures/**",
|
"**/fixtures/**",
|
||||||
|
"**/_temp-fixtures/**",
|
||||||
"**/vendor/**",
|
"**/vendor/**",
|
||||||
"**/.vercel/**",
|
"**/.vercel/**",
|
||||||
],
|
],
|
||||||
|
|
|
@ -87,6 +87,9 @@
|
||||||
"allowAny": [
|
"allowAny": [
|
||||||
"astro"
|
"astro"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"patchedDependencies": {
|
||||||
|
"fs-fixture@2.4.0": "patches/fs-fixture@2.4.0.patch"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,14 +112,15 @@
|
||||||
"build": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm && tsc",
|
"build": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm && tsc",
|
||||||
"build:ci": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm",
|
"build:ci": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm",
|
||||||
"dev": "astro-scripts dev --copy-wasm --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.{ts,js}\"",
|
"dev": "astro-scripts dev --copy-wasm --prebuild \"src/runtime/server/astro-island.ts\" --prebuild \"src/runtime/client/{idle,load,media,only,visible}.ts\" \"src/**/*.{ts,js}\"",
|
||||||
"test": "pnpm run test:node && pnpm run test:types",
|
"test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:types",
|
||||||
"test:match": "pnpm run test:node --match",
|
"test:match": "astro-scripts test \"test/**/*.test.js\" --match",
|
||||||
"test:e2e": "pnpm test:e2e:chrome && pnpm test:e2e:firefox",
|
"test:e2e": "pnpm test:e2e:chrome && pnpm test:e2e:firefox",
|
||||||
"test:e2e:match": "playwright test -g",
|
"test:e2e:match": "playwright test -g",
|
||||||
"test:e2e:chrome": "playwright test",
|
"test:e2e:chrome": "playwright test",
|
||||||
"test:e2e:firefox": "playwright test --config playwright.firefox.config.js",
|
"test:e2e:firefox": "playwright test --config playwright.firefox.config.js",
|
||||||
"test:types": "tsc --project tsconfig.tests.json",
|
"test:types": "tsc --project tsconfig.tests.json",
|
||||||
"test:node": "astro-scripts test \"test/**/*.test.js\""
|
"test:unit": "astro-scripts test \"test/units/**/*.test.js\" --teardown ./test/units/teardown.js",
|
||||||
|
"test:integration": "astro-scripts test \"test/*.test.js\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/compiler": "^2.10.3",
|
"@astrojs/compiler": "^2.10.3",
|
||||||
|
@ -210,9 +211,9 @@
|
||||||
"eol": "^0.10.0",
|
"eol": "^0.10.0",
|
||||||
"execa": "^8.0.1",
|
"execa": "^8.0.1",
|
||||||
"expect-type": "^1.1.0",
|
"expect-type": "^1.1.0",
|
||||||
|
"fs-fixture": "^2.4.0",
|
||||||
"mdast-util-mdx": "^3.0.0",
|
"mdast-util-mdx": "^3.0.0",
|
||||||
"mdast-util-mdx-jsx": "^3.1.3",
|
"mdast-util-mdx-jsx": "^3.1.3",
|
||||||
"memfs": "^4.14.0",
|
|
||||||
"node-mocks-http": "^1.16.1",
|
"node-mocks-http": "^1.16.1",
|
||||||
"parse-srcset": "^1.0.2",
|
"parse-srcset": "^1.0.2",
|
||||||
"rehype-autolink-headings": "^7.1.0",
|
"rehype-autolink-headings": "^7.1.0",
|
||||||
|
|
|
@ -77,6 +77,9 @@ export default function createVitePluginAstroServer({
|
||||||
}
|
}
|
||||||
|
|
||||||
process.on('unhandledRejection', handleUnhandledRejection);
|
process.on('unhandledRejection', handleUnhandledRejection);
|
||||||
|
viteServer.httpServer?.on('close', () => {
|
||||||
|
process.off('unhandledRejection', handleUnhandledRejection);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// Push this middleware to the front of the stack so that it can intercept responses.
|
// Push this middleware to the front of the stack so that it can intercept responses.
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { defineConfig } from 'astro/config';
|
|
||||||
|
|
||||||
// https://astro.build/config
|
|
||||||
export default defineConfig({});
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@test/content-mixed-errors",
|
|
||||||
"type": "module",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "astro dev",
|
|
||||||
"start": "astro dev",
|
|
||||||
"build": "astro build",
|
|
||||||
"preview": "astro preview",
|
|
||||||
"astro": "astro"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"astro": "workspace:*"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Placeholder"
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
---
|
|
||||||
title: Placeholder post
|
|
||||||
---
|
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
try {
|
|
||||||
await getCollection('authors')
|
|
||||||
} catch (e) {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1>Worked</h1>
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
import { getCollection } from 'astro:content';
|
|
||||||
|
|
||||||
await getCollection('blog')
|
|
||||||
---
|
|
||||||
|
|
||||||
<h1>Worked</h1>
|
|
8
packages/astro/test/units/_temp-fixtures/package.json
Normal file
8
packages/astro/test/units/_temp-fixtures/package.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "astro-temp-fixtures",
|
||||||
|
"description": "This directory contains nested directories of dynamically created unit test fixtures. The deps here can be used by them",
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/mdx": "workspace:*",
|
||||||
|
"astro": "workspace:*"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,19 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { createFixture, runInContainer } from '../test-utils.js';
|
||||||
import { createFs, runInContainer } from '../test-utils.js';
|
|
||||||
|
|
||||||
const root = new URL('../../fixtures/tailwindcss-ts/', import.meta.url);
|
|
||||||
|
|
||||||
describe('Astro config formats', () => {
|
describe('Astro config formats', () => {
|
||||||
it('An mjs config can import TypeScript modules', async () => {
|
it('An mjs config can import TypeScript modules', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': ``,
|
||||||
'/src/pages/index.astro': ``,
|
'/src/stuff.ts': `export default 'works';`,
|
||||||
'/src/stuff.ts': `export default 'works';`,
|
'/astro.config.mjs': `\
|
||||||
'/astro.config.mjs': `
|
|
||||||
import stuff from './src/stuff.ts';
|
import stuff from './src/stuff.ts';
|
||||||
export default {}
|
export default {}
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, () => {
|
await runInContainer({ inlineConfig: { root: fixture.path } }, () => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
|
|
@ -1,33 +1,16 @@
|
||||||
import nodeFS from 'node:fs';
|
|
||||||
import path from 'node:path';
|
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { attachContentServerListeners } from '../../../dist/content/index.js';
|
import { attachContentServerListeners } from '../../../dist/content/index.js';
|
||||||
import { createFs, runInContainer, triggerFSEvent } from '../test-utils.js';
|
import { createFixture, runInContainer } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
function getTypesDts() {
|
|
||||||
const typesdtsURL = new URL('../../../templates/content/types.d.ts', import.meta.url);
|
|
||||||
const relpath = path
|
|
||||||
.relative(fileURLToPath(root), fileURLToPath(typesdtsURL))
|
|
||||||
.replace(/\\/g, '/');
|
|
||||||
return {
|
|
||||||
[relpath]: nodeFS.readFileSync(typesdtsURL, 'utf-8'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('frontmatter', () => {
|
describe('frontmatter', () => {
|
||||||
it('errors in content/ does not crash server', async () => {
|
it('errors in content/ does not crash server', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/content/posts/blog.md': `\
|
||||||
...getTypesDts(),
|
|
||||||
'/src/content/posts/blog.md': `
|
|
||||||
---
|
---
|
||||||
title: One
|
title: One
|
||||||
---
|
---
|
||||||
`,
|
`,
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `\
|
||||||
import { defineCollection, z } from 'astro:content';
|
import { defineCollection, z } from 'astro:content';
|
||||||
|
|
||||||
const posts = defineCollection({
|
const posts = defineCollection({
|
||||||
|
@ -38,7 +21,7 @@ describe('frontmatter', () => {
|
||||||
posts
|
posts
|
||||||
};
|
};
|
||||||
`,
|
`,
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `\
|
||||||
---
|
---
|
||||||
---
|
---
|
||||||
<html>
|
<html>
|
||||||
|
@ -48,14 +31,12 @@ describe('frontmatter', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
|
await runInContainer({ inlineConfig: { root: fixture.path } }, async (container) => {
|
||||||
await attachContentServerListeners(container);
|
await attachContentServerListeners(container);
|
||||||
|
|
||||||
fs.writeFileFromRootSync(
|
await fixture.writeFile(
|
||||||
'/src/content/posts/blog.md',
|
'/src/content/posts/blog.md',
|
||||||
`
|
`
|
||||||
---
|
---
|
||||||
|
@ -64,7 +45,6 @@ describe('frontmatter', () => {
|
||||||
---
|
---
|
||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
triggerFSEvent(container, fs, '/src/content/posts/blog.md', 'change');
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
// Note, if we got here, it didn't crash
|
// Note, if we got here, it didn't crash
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/**
|
|
||||||
* correctPath.js <https://github.com/streamich/fs-monkey/blob/af36a890d8070b25b9eae7178824f653bad5621f/src/correctPath.js>
|
|
||||||
* Taken from:
|
|
||||||
* https://github.com/streamich/fs-monkeys
|
|
||||||
*/
|
|
||||||
|
|
||||||
const isWin = process.platform === 'win32';
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* removeTrailingSeparator <https://github.com/darsain/remove-trailing-separator>
|
|
||||||
*
|
|
||||||
* Inlined from:
|
|
||||||
* Copyright (c) darsain.
|
|
||||||
* Released under the ISC License.
|
|
||||||
*/
|
|
||||||
function removeTrailingSeparator(str) {
|
|
||||||
let i = str.length - 1;
|
|
||||||
if (i < 2) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
while (isSeparator(str, i)) {
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return str.substr(0, i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSeparator(str, i) {
|
|
||||||
let char = str[i];
|
|
||||||
return i > 0 && (char === '/' || (isWin && char === '\\'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* normalize-path <https://github.com/jonschlinkert/normalize-path>
|
|
||||||
*
|
|
||||||
* Inlined from:
|
|
||||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/
|
|
||||||
function normalizePath(str, stripTrailing) {
|
|
||||||
if (typeof str !== 'string') {
|
|
||||||
throw new TypeError('expected a string');
|
|
||||||
}
|
|
||||||
str = str.replace(/[\\/]+/g, '/');
|
|
||||||
if (stripTrailing !== false) {
|
|
||||||
str = removeTrailingSeparator(str);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* unixify <https://github.com/jonschlinkert/unixify>
|
|
||||||
*
|
|
||||||
* Inlined from:
|
|
||||||
* Copyright (c) 2014, 2017, Jon Schlinkert.
|
|
||||||
* Released under the MIT License.
|
|
||||||
*/
|
|
||||||
export function unixify(filepath, stripTrailing = true) {
|
|
||||||
if (isWin) {
|
|
||||||
filepath = normalizePath(filepath, stripTrailing);
|
|
||||||
return filepath.replace(/^([a-zA-Z]+:|\.\/)/, '');
|
|
||||||
}
|
|
||||||
return filepath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Corrects a windows path to unix format (including \\?\c:...)
|
|
||||||
*/
|
|
||||||
export function correctPath(filepath) {
|
|
||||||
return unixify(filepath.replace(/^\\\\\?\\.:\\/, '\\'));
|
|
||||||
}
|
|
|
@ -1,26 +1,19 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
describe('base configuration', () => {
|
describe('base configuration', () => {
|
||||||
describe('with trailingSlash: "never"', () => {
|
describe('with trailingSlash: "never"', () => {
|
||||||
describe('index route', () => {
|
describe('index route', () => {
|
||||||
it('Requests that include a trailing slash 404', async () => {
|
it('Requests that include a trailing slash 404', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>testing</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>testing</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/docs',
|
base: '/docs',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
},
|
},
|
||||||
|
@ -38,18 +31,15 @@ describe('base configuration', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Requests that exclude a trailing slash 200', async () => {
|
it('Requests that exclude a trailing slash 200', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>testing</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>testing</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
fs,
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/docs',
|
base: '/docs',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
},
|
},
|
||||||
|
@ -69,18 +59,14 @@ describe('base configuration', () => {
|
||||||
|
|
||||||
describe('sub route', () => {
|
describe('sub route', () => {
|
||||||
it('Requests that include a trailing slash 404', async () => {
|
it('Requests that include a trailing slash 404', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/sub/index.astro': `<h1>testing</h1>`,
|
||||||
'/src/pages/sub/index.astro': `<h1>testing</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/docs',
|
base: '/docs',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
},
|
},
|
||||||
|
@ -98,18 +84,14 @@ describe('base configuration', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Requests that exclude a trailing slash 200', async () => {
|
it('Requests that exclude a trailing slash 200', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/sub/index.astro': `<h1>testing</h1>`,
|
||||||
'/src/pages/sub/index.astro': `<h1>testing</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/docs',
|
base: '/docs',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,129 +1,146 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import _sync from '../../../dist/core/sync/index.js';
|
import _sync from '../../../dist/core/sync/index.js';
|
||||||
import { createFsWithFallback } from '../test-utils.js';
|
import { createFixture } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/content-mixed-errors/', import.meta.url);
|
async function sync(root) {
|
||||||
|
|
||||||
async function sync({ fs }) {
|
|
||||||
try {
|
try {
|
||||||
await _sync(
|
await _sync({
|
||||||
{
|
root,
|
||||||
root: fileURLToPath(root),
|
logLevel: 'silent',
|
||||||
logLevel: 'silent',
|
});
|
||||||
},
|
|
||||||
{
|
|
||||||
fs,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
} catch (_) {
|
} catch {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const baseFileTree = {
|
||||||
|
'/src/content/authors/placeholder.json': `{ "name": "Placeholder" }`,
|
||||||
|
'/src/content/blog/placeholder.md': `\
|
||||||
|
---
|
||||||
|
title: Placeholder post
|
||||||
|
---
|
||||||
|
`,
|
||||||
|
'/src/pages/authors.astro': `\
|
||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
try {
|
||||||
|
await getCollection('authors')
|
||||||
|
} catch (e) {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Worked</h1>
|
||||||
|
`,
|
||||||
|
'/src/pages/blog.astro': `\
|
||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
|
await getCollection('blog')
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Worked</h1>`,
|
||||||
|
};
|
||||||
|
|
||||||
describe('Content Collections - mixed content errors', () => {
|
describe('Content Collections - mixed content errors', () => {
|
||||||
it('raises "mixed content" error when content in data collection', async () => {
|
it('raises "mixed content" error when content in data collection', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/authors/ben.md': `---
|
'/src/content/authors/ben.md': `\
|
||||||
|
---
|
||||||
name: Ben
|
name: Ben
|
||||||
---
|
---
|
||||||
|
|
||||||
# Ben`,
|
# Ben
|
||||||
'/src/content/authors/tony.json': `{ "name": "Tony" }`,
|
`,
|
||||||
'/src/content/config.ts': `
|
'/src/content/authors/tony.json': `{ "name": "Tony" }`,
|
||||||
|
'/src/content/config.ts': `\
|
||||||
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
import { z, defineCollection } from 'astro:content';
|
const authors = defineCollection({
|
||||||
|
type: 'data',
|
||||||
|
schema: z.object({
|
||||||
|
name: z.string(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const authors = defineCollection({
|
export const collections = { authors };
|
||||||
type: 'data',
|
`,
|
||||||
schema: z.object({
|
});
|
||||||
name: z.string(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { authors };`,
|
assert.equal(await sync(fixture.path), 1);
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.equal(await sync({ fs }), 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('raises "mixed content" error when data in content collection', async () => {
|
it('raises "mixed content" error when data in content collection', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/blog/post.md': `---
|
'/src/content/blog/post.md': `\
|
||||||
|
---
|
||||||
title: Post
|
title: Post
|
||||||
---
|
---
|
||||||
|
|
||||||
# Post`,
|
# Post
|
||||||
'/src/content/blog/post.yaml': `title: YAML Post`,
|
`,
|
||||||
'/src/content/config.ts': `
|
'/src/content/blog/post.yaml': `title: YAML Post`,
|
||||||
|
'/src/content/config.ts': `\
|
||||||
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
import { z, defineCollection } from 'astro:content';
|
const blog = defineCollection({
|
||||||
|
type: 'content',
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const blog = defineCollection({
|
export const collections = { blog };
|
||||||
type: 'content',
|
`,
|
||||||
schema: z.object({
|
});
|
||||||
title: z.string(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { blog };`,
|
assert.equal(await sync(fixture.path), 1);
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.equal(await sync({ fs }), 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('raises error when data collection configured as content collection', async () => {
|
it('raises error when data collection configured as content collection', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/banners/welcome.json': `{ "src": "/example", "alt": "Welcome" }`,
|
'/src/content/banners/welcome.json': `{ "src": "/example", "alt": "Welcome" }`,
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `\
|
||||||
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
import { z, defineCollection } from 'astro:content';
|
const banners = defineCollection({
|
||||||
|
schema: z.object({
|
||||||
|
src: z.string(),
|
||||||
|
alt: z.string(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const banners = defineCollection({
|
export const collections = { banners };
|
||||||
schema: z.object({
|
`,
|
||||||
src: z.string(),
|
});
|
||||||
alt: z.string(),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = { banners };`,
|
assert.equal(await sync(fixture.path), 1);
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.equal(await sync({ fs }), 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not raise error for empty collection with config', async () => {
|
it('does not raise error for empty collection with config', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
// Add placeholder to ensure directory exists
|
// Add placeholder to ensure directory exists
|
||||||
'/src/content/i18n/_placeholder.txt': 'Need content here',
|
'/src/content/i18n/_placeholder.txt': 'Need content here',
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `\
|
||||||
import { z, defineCollection } from 'astro:content';
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
const i18n = defineCollection({
|
const i18n = defineCollection({
|
||||||
type: 'data',
|
type: 'data',
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
greeting: z.string(),
|
greeting: z.string(),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const collections = { i18n };`,
|
export const collections = { i18n };
|
||||||
},
|
`,
|
||||||
root,
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const res = await sync({ fs });
|
assert.equal(await sync(fixture.path), 0);
|
||||||
assert.equal(res, 0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +1,39 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
|
|
||||||
import { attachContentServerListeners } from '../../../dist/content/server-listeners.js';
|
import { attachContentServerListeners } from '../../../dist/content/server-listeners.js';
|
||||||
import { createFsWithFallback, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/content/', import.meta.url);
|
const baseFileTree = {
|
||||||
|
'astro.config.mjs': `\
|
||||||
|
import mdx from '@astrojs/mdx';
|
||||||
|
export default {
|
||||||
|
integrations: [mdx()]
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
'/src/content/blog/promo/_launch-week-styles.css': `\
|
||||||
|
body {
|
||||||
|
font-family: 'Comic Sans MS', sans-serif;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
'/src/content/blog/promo/launch-week.mdx': `\
|
||||||
|
---
|
||||||
|
title: 'Launch week!'
|
||||||
|
description: 'Join us for the exciting launch of SPACE BLOG'
|
||||||
|
publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)'
|
||||||
|
tags: ['announcement']
|
||||||
|
---
|
||||||
|
|
||||||
|
import './_launch-week-styles.css';
|
||||||
|
|
||||||
|
Join us for the space blog launch!
|
||||||
|
|
||||||
|
- THIS THURSDAY
|
||||||
|
- Houston, TX
|
||||||
|
- Dress code: **interstellar casual** ✨
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
/** @type {typeof runInContainer} */
|
/** @type {typeof runInContainer} */
|
||||||
async function runInContainerWithContentListeners(params, callback) {
|
async function runInContainerWithContentListeners(params, callback) {
|
||||||
|
@ -18,9 +45,9 @@ async function runInContainerWithContentListeners(params, callback) {
|
||||||
|
|
||||||
describe('Content Collections - render()', () => {
|
describe('Content Collections - render()', () => {
|
||||||
it('can be called in a page component', async () => {
|
it('can be called in a page component', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `
|
||||||
import { z, defineCollection } from 'astro:content';
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
const blog = defineCollection({
|
const blog = defineCollection({
|
||||||
|
@ -32,7 +59,7 @@ describe('Content Collections - render()', () => {
|
||||||
|
|
||||||
export const collections = { blog };
|
export const collections = { blog };
|
||||||
`,
|
`,
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
const blog = await getCollection('blog');
|
const blog = await getCollection('blog');
|
||||||
|
@ -47,15 +74,12 @@ describe('Content Collections - render()', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainerWithContentListeners(
|
await runInContainerWithContentListeners(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -79,9 +103,9 @@ describe('Content Collections - render()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be used in a layout component', async () => {
|
it('can be used in a layout component', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/components/Layout.astro': `
|
'/src/components/Layout.astro': `
|
||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
const blog = await getCollection('blog');
|
const blog = await getCollection('blog');
|
||||||
|
@ -99,7 +123,7 @@ describe('Content Collections - render()', () => {
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
`,
|
`,
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `
|
||||||
---
|
---
|
||||||
import Layout from '../components/Layout.astro';
|
import Layout from '../components/Layout.astro';
|
||||||
---
|
---
|
||||||
|
@ -107,15 +131,12 @@ describe('Content Collections - render()', () => {
|
||||||
<h1 slot="title">Index page</h2>
|
<h1 slot="title">Index page</h2>
|
||||||
</Layout>
|
</Layout>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainerWithContentListeners(
|
await runInContainerWithContentListeners(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -139,9 +160,9 @@ describe('Content Collections - render()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be used in a slot', async () => {
|
it('can be used in a slot', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `
|
||||||
import { z, defineCollection } from 'astro:content';
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
const blog = defineCollection({
|
const blog = defineCollection({
|
||||||
|
@ -153,7 +174,7 @@ describe('Content Collections - render()', () => {
|
||||||
|
|
||||||
export const collections = { blog };
|
export const collections = { blog };
|
||||||
`,
|
`,
|
||||||
'/src/components/Layout.astro': `
|
'/src/components/Layout.astro': `
|
||||||
<html>
|
<html>
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -164,7 +185,7 @@ describe('Content Collections - render()', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `
|
||||||
---
|
---
|
||||||
import Layout from '../components/Layout.astro';
|
import Layout from '../components/Layout.astro';
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
@ -177,15 +198,12 @@ describe('Content Collections - render()', () => {
|
||||||
<Content slot="main" />
|
<Content slot="main" />
|
||||||
</Layout>
|
</Layout>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainerWithContentListeners(
|
await runInContainerWithContentListeners(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -209,9 +227,9 @@ describe('Content Collections - render()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be called from any js/ts file', async () => {
|
it('can be called from any js/ts file', async () => {
|
||||||
const fs = createFsWithFallback(
|
const fixture = await createFixture({
|
||||||
{
|
...baseFileTree,
|
||||||
'/src/content/config.ts': `
|
'/src/content/config.ts': `
|
||||||
import { z, defineCollection } from 'astro:content';
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
const blog = defineCollection({
|
const blog = defineCollection({
|
||||||
|
@ -223,7 +241,7 @@ describe('Content Collections - render()', () => {
|
||||||
|
|
||||||
export const collections = { blog };
|
export const collections = { blog };
|
||||||
`,
|
`,
|
||||||
'/src/launch-week.ts': `
|
'/src/launch-week.ts': `
|
||||||
import { getCollection } from 'astro:content';
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
export let Content;
|
export let Content;
|
||||||
|
@ -234,7 +252,7 @@ describe('Content Collections - render()', () => {
|
||||||
|
|
||||||
Content = mod.Content;
|
Content = mod.Content;
|
||||||
`,
|
`,
|
||||||
'/src/pages/index.astro': `
|
'/src/pages/index.astro': `
|
||||||
---
|
---
|
||||||
import { Content } from '../launch-week.ts';
|
import { Content } from '../launch-week.ts';
|
||||||
---
|
---
|
||||||
|
@ -246,15 +264,12 @@ describe('Content Collections - render()', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainerWithContentListeners(
|
await runInContainerWithContentListeners(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,21 +1,12 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import {
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
createFs,
|
|
||||||
createRequestAndResponse,
|
|
||||||
runInContainer,
|
|
||||||
triggerFSEvent,
|
|
||||||
} from '../test-utils.js';
|
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
describe('dev container', () => {
|
describe('dev container', () => {
|
||||||
it('can render requests', async () => {
|
it('can render requests', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
---
|
||||||
const name = 'Testing';
|
const name = 'Testing';
|
||||||
---
|
---
|
||||||
|
@ -26,11 +17,9 @@ describe('dev container', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
|
await runInContainer({ inlineConfig: { root: fixture.path } }, async (container) => {
|
||||||
const { req, res, text } = createRequestAndResponse({
|
const { req, res, text } = createRequestAndResponse({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/',
|
url: '/',
|
||||||
|
@ -43,89 +32,16 @@ describe('dev container', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('HMR only short circuits on previously cached modules', async () => {
|
|
||||||
const fs = createFs(
|
|
||||||
{
|
|
||||||
'/src/components/Header.astro': `
|
|
||||||
<h1>{Astro.props.title}</h1>
|
|
||||||
`,
|
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
|
||||||
import Header from '../components/Header.astro';
|
|
||||||
const name = 'Testing';
|
|
||||||
---
|
|
||||||
<html>
|
|
||||||
<head><title>{name}</title></head>
|
|
||||||
<body class="one">
|
|
||||||
<Header title={name} />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`,
|
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
|
|
||||||
let r = createRequestAndResponse({
|
|
||||||
method: 'GET',
|
|
||||||
url: '/',
|
|
||||||
});
|
|
||||||
container.handle(r.req, r.res);
|
|
||||||
let html = await r.text();
|
|
||||||
let $ = cheerio.load(html);
|
|
||||||
assert.equal($('body.one').length, 1);
|
|
||||||
|
|
||||||
fs.writeFileFromRootSync(
|
|
||||||
'/src/components/Header.astro',
|
|
||||||
`
|
|
||||||
<h1>{Astro.props.title}</h1>
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
triggerFSEvent(container, fs, '/src/components/Header.astro', 'change');
|
|
||||||
|
|
||||||
fs.writeFileFromRootSync(
|
|
||||||
'/src/pages/index.astro',
|
|
||||||
`
|
|
||||||
---
|
|
||||||
import Header from '../components/Header.astro';
|
|
||||||
const name = 'Testing';
|
|
||||||
---
|
|
||||||
<html>
|
|
||||||
<head><title>{name}</title></head>
|
|
||||||
<body class="two">
|
|
||||||
<Header title={name} />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`,
|
|
||||||
);
|
|
||||||
triggerFSEvent(container, fs, '/src/pages/index.astro', 'change');
|
|
||||||
|
|
||||||
r = createRequestAndResponse({
|
|
||||||
method: 'GET',
|
|
||||||
url: '/',
|
|
||||||
});
|
|
||||||
container.handle(r.req, r.res);
|
|
||||||
html = await r.text();
|
|
||||||
$ = cheerio.load(html);
|
|
||||||
assert.equal($('body.one').length, 0);
|
|
||||||
assert.equal($('body.two').length, 1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Allows dynamic segments in injected routes', async () => {
|
it('Allows dynamic segments in injected routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/components/test.astro': `<h1>{Astro.params.slug}</h1>`,
|
||||||
'/src/components/test.astro': `<h1>{Astro.params.slug}</h1>`,
|
'/src/pages/test-[slug].astro': `<h1>{Astro.params.slug}</h1>`,
|
||||||
'/src/pages/test-[slug].astro': `<h1>{Astro.params.slug}</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
integrations: [
|
integrations: [
|
||||||
{
|
{
|
||||||
|
@ -164,19 +80,15 @@ describe('dev container', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Serves injected 404 route for any 404', async () => {
|
it('Serves injected 404 route for any 404', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/components/404.astro': `<h1>Custom 404</h1>`,
|
||||||
'/src/components/404.astro': `<h1>Custom 404</h1>`,
|
'/src/pages/page.astro': `<h1>Regular page</h1>`,
|
||||||
'/src/pages/page.astro': `<h1>Regular page</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
integrations: [
|
integrations: [
|
||||||
{
|
{
|
||||||
|
@ -226,10 +138,14 @@ describe('dev container', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('items in public/ are not available from root when using a base', async () => {
|
it('items in public/ are not available from root when using a base', async () => {
|
||||||
|
const fixture = await createFixture({
|
||||||
|
'/public/test.txt': `Test`,
|
||||||
|
});
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/sub/',
|
base: '/sub/',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -260,7 +176,11 @@ describe('dev container', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('items in public/ are available from root when not using a base', async () => {
|
it('items in public/ are available from root when not using a base', async () => {
|
||||||
await runInContainer({ inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
|
const fixture = await createFixture({
|
||||||
|
'/public/test.txt': `Test`,
|
||||||
|
});
|
||||||
|
|
||||||
|
await runInContainer({ inlineConfig: { root: fixture.path } }, async (container) => {
|
||||||
// Try the root path
|
// Try the root path
|
||||||
let r = createRequestAndResponse({
|
let r = createRequestAndResponse({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
const root = new URL('../../fixtures/alias/', import.meta.url);
|
||||||
|
|
||||||
describe('head injection', () => {
|
describe('head injection', () => {
|
||||||
it('Dynamic injection from component created in the page frontmatter', async () => {
|
it('Dynamic injection from component created in the page frontmatter', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture(
|
||||||
{
|
{
|
||||||
'/src/components/Other.astro': `
|
'/src/components/Other.astro': `
|
||||||
<style>
|
<style>
|
||||||
|
@ -64,9 +63,8 @@ describe('head injection', () => {
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -87,7 +85,7 @@ describe('head injection', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Dynamic injection from a layout component', async () => {
|
it('Dynamic injection from a layout component', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture(
|
||||||
{
|
{
|
||||||
'/src/components/Other.astro': `
|
'/src/components/Other.astro': `
|
||||||
<style>
|
<style>
|
||||||
|
@ -164,9 +162,8 @@ describe('head injection', () => {
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
vite: { server: { middlewareMode: true } },
|
vite: { server: { middlewareMode: true } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
describe('hydration', () => {
|
describe('hydration', () => {
|
||||||
it(
|
it(
|
||||||
'should not crash when reassigning a hydrated component',
|
'should not crash when reassigning a hydrated component',
|
||||||
{ skip: true, todo: "It seems that `components/Client.svelte` isn't found" },
|
{ skip: true, todo: "It seems that `components/Client.svelte` isn't found" },
|
||||||
async () => {
|
async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
---
|
||||||
import Svelte from '../components/Client.svelte';
|
import Svelte from '../components/Client.svelte';
|
||||||
const Foo = Svelte;
|
const Foo = Svelte;
|
||||||
|
@ -26,15 +22,12 @@ describe('hydration', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
logLevel: 'silent',
|
logLevel: 'silent',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createContainerWithAutomaticRestart,
|
createContainerWithAutomaticRestart,
|
||||||
startContainer,
|
startContainer,
|
||||||
} from '../../../dist/core/dev/index.js';
|
} from '../../../dist/core/dev/index.js';
|
||||||
import { createFs, createRequestAndResponse, triggerFSEvent } from '../test-utils.js';
|
import { createFixture, createRequestAndResponse } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
/** @type {import('astro').AstroInlineConfig} */
|
||||||
|
const defaultInlineConfig = {
|
||||||
|
logLevel: 'silent',
|
||||||
|
};
|
||||||
|
|
||||||
function isStarted(container) {
|
function isStarted(container) {
|
||||||
return !!container.viteServer.httpServer?.listening;
|
return !!container.viteServer.httpServer?.listening;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('dev container restarts', () => {
|
// Checking for restarts may hang if no restarts happen, so set a 20s timeout for each test
|
||||||
|
describe('dev container restarts', { timeout: 20000 }, () => {
|
||||||
it('Surfaces config errors on restarts', async () => {
|
it('Surfaces config errors on restarts', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
<html>
|
<html>
|
||||||
<head><title>Test</title></head>
|
<head><title>Test</title></head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -27,16 +29,14 @@ describe('dev container restarts', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
'/astro.config.mjs': `
|
'/astro.config.mjs': ``,
|
||||||
|
});
|
||||||
`,
|
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -52,40 +52,37 @@ describe('dev container restarts', () => {
|
||||||
|
|
||||||
// Create an error
|
// Create an error
|
||||||
let restartComplete = restart.restarted();
|
let restartComplete = restart.restarted();
|
||||||
fs.writeFileFromRootSync('/astro.config.mjs', 'const foo = bar');
|
await fixture.writeFile('/astro.config.mjs', 'const foo = bar');
|
||||||
|
// TODO: fix this hack
|
||||||
// Vite watches the real filesystem, so we have to mock this part. It's not so bad.
|
|
||||||
restart.container.viteServer.watcher.emit(
|
restart.container.viteServer.watcher.emit(
|
||||||
'change',
|
'change',
|
||||||
fs.getFullyResolvedPath('/astro.config.mjs'),
|
fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Wait for the restart to finish
|
// Wait for the restart to finish
|
||||||
let hmrError = await restartComplete;
|
let hmrError = await restartComplete;
|
||||||
assert.notEqual(typeof hmrError, 'undefined');
|
assert.ok(hmrError instanceof Error);
|
||||||
|
|
||||||
// Do it a second time to make sure we are still watching
|
// Do it a second time to make sure we are still watching
|
||||||
|
|
||||||
restartComplete = restart.restarted();
|
restartComplete = restart.restarted();
|
||||||
fs.writeFileFromRootSync('/astro.config.mjs', 'const foo = bar2');
|
await fixture.writeFile('/astro.config.mjs', 'const foo = bar2');
|
||||||
|
// TODO: fix this hack
|
||||||
// Vite watches the real filesystem, so we have to mock this part. It's not so bad.
|
|
||||||
restart.container.viteServer.watcher.emit(
|
restart.container.viteServer.watcher.emit(
|
||||||
'change',
|
'change',
|
||||||
fs.getFullyResolvedPath('/astro.config.mjs'),
|
fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
|
||||||
);
|
);
|
||||||
|
|
||||||
hmrError = await restartComplete;
|
hmrError = await restartComplete;
|
||||||
assert.notEqual(typeof hmrError, 'undefined');
|
assert.ok(hmrError instanceof Error);
|
||||||
} finally {
|
} finally {
|
||||||
await restart.container.close();
|
await restart.container.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Restarts the container if previously started', async () => {
|
it('Restarts the container if previously started', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
<html>
|
<html>
|
||||||
<head><title>Test</title></head>
|
<head><title>Test</title></head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -93,14 +90,14 @@ describe('dev container restarts', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
'/astro.config.mjs': ``,
|
'/astro.config.mjs': ``,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await startContainer(restart.container);
|
await startContainer(restart.container);
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
@ -108,7 +105,12 @@ describe('dev container restarts', () => {
|
||||||
try {
|
try {
|
||||||
// Trigger a change
|
// Trigger a change
|
||||||
let restartComplete = restart.restarted();
|
let restartComplete = restart.restarted();
|
||||||
triggerFSEvent(restart.container, fs, '/astro.config.mjs', 'change');
|
await fixture.writeFile('/astro.config.mjs', '');
|
||||||
|
// TODO: fix this hack
|
||||||
|
restart.container.viteServer.watcher.emit(
|
||||||
|
'change',
|
||||||
|
fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
|
||||||
|
);
|
||||||
await restartComplete;
|
await restartComplete;
|
||||||
|
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
@ -118,18 +120,16 @@ describe('dev container restarts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Is able to restart project using Tailwind + astro.config.ts', async () => {
|
it('Is able to restart project using Tailwind + astro.config.ts', async () => {
|
||||||
const troot = new URL('../../fixtures/tailwindcss-ts/', import.meta.url);
|
const fixture = await createFixture({
|
||||||
const fs = createFs(
|
'/src/pages/index.astro': ``,
|
||||||
{
|
'/astro.config.ts': ``,
|
||||||
'/src/pages/index.astro': ``,
|
});
|
||||||
'/astro.config.ts': ``,
|
|
||||||
},
|
|
||||||
troot,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await startContainer(restart.container);
|
await startContainer(restart.container);
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
@ -137,7 +137,12 @@ describe('dev container restarts', () => {
|
||||||
try {
|
try {
|
||||||
// Trigger a change
|
// Trigger a change
|
||||||
let restartComplete = restart.restarted();
|
let restartComplete = restart.restarted();
|
||||||
triggerFSEvent(restart.container, fs, '/astro.config.ts', 'change');
|
await fixture.writeFile('/astro.config.ts', '');
|
||||||
|
// TODO: fix this hack
|
||||||
|
restart.container.viteServer.watcher.emit(
|
||||||
|
'change',
|
||||||
|
fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
|
||||||
|
);
|
||||||
await restartComplete;
|
await restartComplete;
|
||||||
|
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
@ -147,24 +152,27 @@ describe('dev container restarts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Is able to restart project on package.json changes', async () => {
|
it('Is able to restart project on package.json changes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': ``,
|
||||||
'/src/pages/index.astro': ``,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await startContainer(restart.container);
|
await startContainer(restart.container);
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let restartComplete = restart.restarted();
|
let restartComplete = restart.restarted();
|
||||||
fs.writeFileSync('/package.json', `{}`);
|
await fixture.writeFile('/package.json', `{}`);
|
||||||
triggerFSEvent(restart.container, fs, '/package.json', 'change');
|
// TODO: fix this hack
|
||||||
|
restart.container.viteServer.watcher.emit(
|
||||||
|
'change',
|
||||||
|
fixture.getPath('/package.json').replace(/\\/g, '/'),
|
||||||
|
);
|
||||||
await restartComplete;
|
await restartComplete;
|
||||||
} finally {
|
} finally {
|
||||||
await restart.container.close();
|
await restart.container.close();
|
||||||
|
@ -172,16 +180,15 @@ describe('dev container restarts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Is able to restart on viteServer.restart API call', async () => {
|
it('Is able to restart on viteServer.restart API call', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': ``,
|
||||||
'/src/pages/index.astro': ``,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await startContainer(restart.container);
|
await startContainer(restart.container);
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
@ -196,26 +203,28 @@ describe('dev container restarts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Is able to restart project on .astro/settings.json changes', async () => {
|
it('Is able to restart project on .astro/settings.json changes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': ``,
|
||||||
'/src/pages/index.astro': ``,
|
'/.astro/settings.json': `{}`,
|
||||||
'/.astro/settings.json': `{}`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const restart = await createContainerWithAutomaticRestart({
|
const restart = await createContainerWithAutomaticRestart({
|
||||||
fs,
|
inlineConfig: {
|
||||||
inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
|
...defaultInlineConfig,
|
||||||
|
root: fixture.path,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
await startContainer(restart.container);
|
await startContainer(restart.container);
|
||||||
assert.equal(isStarted(restart.container), true);
|
assert.equal(isStarted(restart.container), true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let restartComplete = restart.restarted();
|
let restartComplete = restart.restarted();
|
||||||
fs.mkdirSync('/.astro/', { recursive: true });
|
await fixture.writeFile('/.astro/settings.json', `{ }`);
|
||||||
fs.writeFileSync('/.astro/settings.json', `{ }`);
|
// TODO: fix this hack
|
||||||
triggerFSEvent(restart.container, fs, '/.astro/settings.json', 'change');
|
restart.container.viteServer.watcher.emit(
|
||||||
|
'change',
|
||||||
|
fixture.getPath('/.astro/settings.json').replace(/\\/g, '/'),
|
||||||
|
);
|
||||||
await restartComplete;
|
await restartComplete;
|
||||||
} finally {
|
} finally {
|
||||||
await restart.container.close();
|
await restart.container.close();
|
||||||
|
|
|
@ -1,30 +1,23 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
describe('core/render chunk', () => {
|
describe('core/render chunk', () => {
|
||||||
it('does not throw on user object with type', async () => {
|
it('does not throw on user object with type', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `\
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
---
|
||||||
const value = { type: 'foobar' }
|
const value = { type: 'foobar' }
|
||||||
---
|
---
|
||||||
<div id="chunk">{value}</div>
|
<div id="chunk">{value}</div>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
logLevel: 'silent',
|
logLevel: 'silent',
|
||||||
integrations: [],
|
integrations: [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
describe('core/render components', () => {
|
describe('core/render components', () => {
|
||||||
it('should sanitize dynamic tags', async () => {
|
it('should sanitize dynamic tags', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
---
|
||||||
const TagA = 'p style=color:red;'
|
const TagA = 'p style=color:red;'
|
||||||
const TagB = 'p><script id="pwnd">console.log("pwnd")</script>'
|
const TagB = 'p><script id="pwnd">console.log("pwnd")</script>'
|
||||||
|
@ -23,15 +19,12 @@ describe('core/render components', () => {
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`,
|
`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
logLevel: 'silent',
|
logLevel: 'silent',
|
||||||
integrations: [],
|
integrations: [],
|
||||||
},
|
},
|
||||||
|
@ -58,9 +51,8 @@ describe('core/render components', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should merge `class` and `class:list`', async () => {
|
it('should merge `class` and `class:list`', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `
|
||||||
'/src/pages/index.astro': `
|
|
||||||
---
|
---
|
||||||
import Class from '../components/Class.astro';
|
import Class from '../components/Class.astro';
|
||||||
import ClassList from '../components/ClassList.astro';
|
import ClassList from '../components/ClassList.astro';
|
||||||
|
@ -74,20 +66,17 @@ describe('core/render components', () => {
|
||||||
<BothFlipped class:list={{ blue: true }} class="red" />
|
<BothFlipped class:list={{ blue: true }} class="red" />
|
||||||
<BothSpread class:list={{ blue: true }} { ...{ class: "red" }} />
|
<BothSpread class:list={{ blue: true }} { ...{ class: "red" }} />
|
||||||
`,
|
`,
|
||||||
'/src/components/Class.astro': `<pre id="class" set:html={JSON.stringify(Astro.props)} />`,
|
'/src/components/Class.astro': `<pre id="class" set:html={JSON.stringify(Astro.props)} />`,
|
||||||
'/src/components/ClassList.astro': `<pre id="class-list" set:html={JSON.stringify(Astro.props)} />`,
|
'/src/components/ClassList.astro': `<pre id="class-list" set:html={JSON.stringify(Astro.props)} />`,
|
||||||
'/src/components/BothLiteral.astro': `<pre id="both-literal" set:html={JSON.stringify(Astro.props)} />`,
|
'/src/components/BothLiteral.astro': `<pre id="both-literal" set:html={JSON.stringify(Astro.props)} />`,
|
||||||
'/src/components/BothFlipped.astro': `<pre id="both-flipped" set:html={JSON.stringify(Astro.props)} />`,
|
'/src/components/BothFlipped.astro': `<pre id="both-flipped" set:html={JSON.stringify(Astro.props)} />`,
|
||||||
'/src/components/BothSpread.astro': `<pre id="both-spread" set:html={JSON.stringify(Astro.props)} />`,
|
'/src/components/BothSpread.astro': `<pre id="both-spread" set:html={JSON.stringify(Astro.props)} />`,
|
||||||
},
|
});
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
await runInContainer(
|
await runInContainer(
|
||||||
{
|
{
|
||||||
fs,
|
|
||||||
inlineConfig: {
|
inlineConfig: {
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
logLevel: 'silent',
|
logLevel: 'silent',
|
||||||
integrations: [],
|
integrations: [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/api-routes/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/response-redirect.ts': `export const GET = ({ url }) => Response.redirect("https://example.com/destination", 307)`,
|
'/src/pages/response-redirect.ts': `export const GET = ({ url }) => Response.redirect("https://example.com/destination", 307)`,
|
||||||
'/src/pages/response.ts': `export const GET = ({ url }) => new Response(null, { headers: { Location: "https://example.com/destination" }, status: 307 })`,
|
'/src/pages/response.ts': `export const GET = ({ url }) => new Response(null, { headers: { Location: "https://example.com/destination" }, status: 307 })`,
|
||||||
|
@ -23,9 +21,9 @@ describe('endpoints', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { describe, it } from 'node:test';
|
import { describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { Logger } from '../../../dist/core/logger/core.js';
|
import { Logger } from '../../../dist/core/logger/core.js';
|
||||||
import { createRouteManifest } from '../../../dist/core/routing/manifest/create.js';
|
import { createRouteManifest } from '../../../dist/core/routing/manifest/create.js';
|
||||||
import { createBasicSettings, createFs } from '../test-utils.js';
|
import { createBasicSettings, createFixture } from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
|
|
||||||
function getManifestRoutes(manifest) {
|
function getManifestRoutes(manifest) {
|
||||||
return manifest.routes.map((route) => ({
|
return manifest.routes.map((route) => ({
|
||||||
|
@ -41,21 +38,17 @@ function assertRouteRelations(routes, relations) {
|
||||||
|
|
||||||
describe('routing - createRouteManifest', () => {
|
describe('routing - createRouteManifest', () => {
|
||||||
it('using trailingSlash: "never" does not match the index route when it contains a trailing slash', async () => {
|
it('using trailingSlash: "never" does not match the index route when it contains a trailing slash', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
});
|
});
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
const [{ pattern }] = manifest.routes;
|
const [{ pattern }] = manifest.routes;
|
||||||
assert.equal(pattern.test(''), true);
|
assert.equal(pattern.test(''), true);
|
||||||
|
@ -63,15 +56,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('endpoint routes are sorted before page routes', async () => {
|
it('endpoint routes are sorted before page routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/[contact].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[contact].astro': `<h1>test</h1>`,
|
'/src/pages/[contact].ts': `<h1>test</h1>`,
|
||||||
'/src/pages/[contact].ts': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
experimental: {
|
experimental: {
|
||||||
|
@ -91,9 +81,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
@ -117,18 +106,15 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('static routes are sorted before dynamic and rest routes', async () => {
|
it('static routes are sorted before dynamic and rest routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/[dynamic].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[dynamic].astro': `<h1>test</h1>`,
|
'/src/pages/[...rest].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[...rest].astro': `<h1>test</h1>`,
|
'/src/pages/static.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/static.astro': `<h1>test</h1>`,
|
'/src/pages/static-[dynamic].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/static-[dynamic].astro': `<h1>test</h1>`,
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
experimental: {
|
experimental: {
|
||||||
|
@ -137,9 +123,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertRouteRelations(getManifestRoutes(manifest), [
|
assertRouteRelations(getManifestRoutes(manifest), [
|
||||||
|
@ -154,21 +139,18 @@ describe('routing - createRouteManifest', () => {
|
||||||
|
|
||||||
it('route sorting with multi-layer index page conflict', async () => {
|
it('route sorting with multi-layer index page conflict', async () => {
|
||||||
// Reproducing regression from https://github.com/withastro/astro/issues/10071
|
// Reproducing regression from https://github.com/withastro/astro/issues/10071
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/a/1.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/a/1.astro': `<h1>test</h1>`,
|
'/src/pages/a/2.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/a/2.astro': `<h1>test</h1>`,
|
'/src/pages/a/3.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/a/3.astro': `<h1>test</h1>`,
|
'/src/pages/modules/[...slug].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/modules/[...slug].astro': `<h1>test</h1>`,
|
'/src/pages/modules/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/modules/index.astro': `<h1>test</h1>`,
|
'/src/pages/test/[...slug].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/test/[...slug].astro': `<h1>test</h1>`,
|
'/src/pages/test/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/test/index.astro': `<h1>test</h1>`,
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
experimental: {
|
experimental: {
|
||||||
|
@ -177,9 +159,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertRouteRelations(getManifestRoutes(manifest), [
|
assertRouteRelations(getManifestRoutes(manifest), [
|
||||||
|
@ -200,24 +181,21 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('route sorting respects the file tree', async () => {
|
it('route sorting respects the file tree', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/[dynamic_folder]/static.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[dynamic_folder]/static.astro': `<h1>test</h1>`,
|
'/src/pages/[dynamic_folder]/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[dynamic_folder]/index.astro': `<h1>test</h1>`,
|
'/src/pages/[dynamic_folder]/[...rest].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[dynamic_folder]/[...rest].astro': `<h1>test</h1>`,
|
'/src/pages/[...rest]/static.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[...rest]/static.astro': `<h1>test</h1>`,
|
'/src/pages/[...rest]/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[...rest]/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
'/src/pages/[dynamic_file].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[dynamic_file].astro': `<h1>test</h1>`,
|
'/src/pages/[...other].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[...other].astro': `<h1>test</h1>`,
|
'/src/pages/static.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/static.astro': `<h1>test</h1>`,
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
experimental: {
|
experimental: {
|
||||||
|
@ -226,9 +204,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assertRouteRelations(getManifestRoutes(manifest), [
|
assertRouteRelations(getManifestRoutes(manifest), [
|
||||||
|
@ -263,15 +240,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('injected routes are sorted in legacy mode above filesystem routes', async () => {
|
it('injected routes are sorted in legacy mode above filesystem routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -289,9 +263,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
@ -315,15 +288,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('injected routes are sorted alongside filesystem routes', async () => {
|
it('injected routes are sorted alongside filesystem routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -345,9 +315,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
@ -371,15 +340,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects are sorted in legacy mode below the filesystem routes', async () => {
|
it('redirects are sorted in legacy mode below the filesystem routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/contributing.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/contributing.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -392,9 +358,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
@ -418,15 +383,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects are sorted alongside the filesystem routes', async () => {
|
it('redirects are sorted alongside the filesystem routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/index.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/index.astro': `<h1>test</h1>`,
|
'/src/pages/blog/contributing.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/blog/contributing.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -445,9 +407,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
@ -471,14 +432,11 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('report colliding static routes', async () => {
|
it('report colliding static routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/contributing.astro': `<h1>test</h1>`,
|
||||||
'/src/pages/contributing.astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -496,9 +454,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifestOptions = {
|
const manifestOptions = {
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { logger, logs } = getLogger();
|
const { logger, logs } = getLogger();
|
||||||
|
@ -523,15 +480,12 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('report colliding SSR dynamic routes', async () => {
|
it('report colliding SSR dynamic routes', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/[foo].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[foo].astro': `<h1>test</h1>`,
|
'/src/pages/[bar].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/[bar].astro': `<h1>test</h1>`,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -542,9 +496,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const manifestOptions = {
|
const manifestOptions = {
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { logger, logs } = getLogger();
|
const { logger, logs } = getLogger();
|
||||||
|
@ -569,16 +522,13 @@ describe('routing - createRouteManifest', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should concatenate each part of the segment. issues#10122', async () => {
|
it('should concatenate each part of the segment. issues#10122', async () => {
|
||||||
const fs = createFs(
|
const fixture = await createFixture({
|
||||||
{
|
'/src/pages/a-[b].astro': `<h1>test</h1>`,
|
||||||
'/src/pages/a-[b].astro': `<h1>test</h1>`,
|
'/src/pages/blog/a-[b].233.ts': ``,
|
||||||
'/src/pages/blog/a-[b].233.ts': ``,
|
});
|
||||||
},
|
|
||||||
root,
|
|
||||||
);
|
|
||||||
|
|
||||||
const settings = await createBasicSettings({
|
const settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
base: '/search',
|
base: '/search',
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
|
@ -599,9 +549,8 @@ describe('routing - createRouteManifest', () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const manifest = createRouteManifest({
|
const manifest = createRouteManifest({
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(getManifestRoutes(manifest), [
|
assert.deepEqual(getManifestRoutes(manifest), [
|
||||||
|
|
|
@ -11,12 +11,11 @@ import { createDevelopmentManifest } from '../../../dist/vite-plugin-astro-serve
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/[serverDynamic].astro': `
|
'/src/pages/[serverDynamic].astro': `
|
||||||
---
|
---
|
||||||
|
@ -131,15 +130,14 @@ describe('Route matching', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
output: 'hybrid',
|
output: 'hybrid',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
@ -149,9 +147,8 @@ describe('Route matching', () => {
|
||||||
pipeline = DevPipeline.create(undefined, { loader, logger: defaultLogger, manifest, settings });
|
pipeline = DevPipeline.create(undefined, { loader, logger: defaultLogger, manifest, settings });
|
||||||
manifestData = createRouteManifest(
|
manifestData = createRouteManifest(
|
||||||
{
|
{
|
||||||
cwd: fileURLToPath(root),
|
cwd: fixture.path,
|
||||||
settings,
|
settings,
|
||||||
fsMod: fs,
|
|
||||||
},
|
},
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/alias/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/[...testSlashTrim].astro': `
|
'/src/pages/[...testSlashTrim].astro': `
|
||||||
---
|
---
|
||||||
|
@ -34,15 +32,14 @@ describe('Route sanitization', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
trailingSlash: 'never',
|
trailingSlash: 'never',
|
||||||
output: 'hybrid',
|
output: 'hybrid',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/api-routes/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/api.ts': `export const GET = () => Response.json({ success: true })`,
|
'/src/pages/api.ts': `export const GET = () => Response.json({ success: true })`,
|
||||||
};
|
};
|
||||||
|
@ -20,15 +18,14 @@ describe('trailingSlash', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
trailingSlash: 'always',
|
trailingSlash: 'always',
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
@ -20,14 +19,13 @@ describe('endpoints', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem, root);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
|
19
packages/astro/test/units/teardown.js
Normal file
19
packages/astro/test/units/teardown.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import fs from 'node:fs';
|
||||||
|
|
||||||
|
export default function teardown(testPassed) {
|
||||||
|
// Delete all directories within `_temp-fixtures` directory if all test passed
|
||||||
|
if (testPassed) {
|
||||||
|
try {
|
||||||
|
const tempFixturesDir = new URL('./_temp-fixtures/', import.meta.url);
|
||||||
|
const entries = fs.readdirSync(tempFixturesDir);
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry === 'package.json' || entry === 'node_modules') continue;
|
||||||
|
const dir = new URL(entry, tempFixturesDir);
|
||||||
|
fs.rmSync(dir, { recursive: true });
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to delete temp fixtures');
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import realFS from 'node:fs';
|
import realFS from 'node:fs';
|
||||||
import npath from 'node:path';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { Volume } from 'memfs';
|
import { createFixture as _createFixture } from 'fs-fixture';
|
||||||
import httpMocks from 'node-mocks-http';
|
import httpMocks from 'node-mocks-http';
|
||||||
import { getDefaultClientDirectives } from '../../dist/core/client-directive/index.js';
|
import { getDefaultClientDirectives } from '../../dist/core/client-directive/index.js';
|
||||||
import { resolveConfig } from '../../dist/core/config/index.js';
|
import { resolveConfig } from '../../dist/core/config/index.js';
|
||||||
|
@ -13,7 +12,6 @@ import { nodeLogDestination } from '../../dist/core/logger/node.js';
|
||||||
import { NOOP_MIDDLEWARE_FN } from '../../dist/core/middleware/noop-middleware.js';
|
import { NOOP_MIDDLEWARE_FN } from '../../dist/core/middleware/noop-middleware.js';
|
||||||
import { Pipeline } from '../../dist/core/render/index.js';
|
import { Pipeline } from '../../dist/core/render/index.js';
|
||||||
import { RouteCache } from '../../dist/core/render/route-cache.js';
|
import { RouteCache } from '../../dist/core/render/route-cache.js';
|
||||||
import { unixify } from './correct-path.js';
|
|
||||||
|
|
||||||
/** @type {import('../../src/core/logger/core').Logger} */
|
/** @type {import('../../src/core/logger/core').Logger} */
|
||||||
export const defaultLogger = new Logger({
|
export const defaultLogger = new Logger({
|
||||||
|
@ -27,102 +25,21 @@ export const silentLogging = {
|
||||||
level: 'error',
|
level: 'error',
|
||||||
};
|
};
|
||||||
|
|
||||||
class VirtualVolume extends Volume {
|
const tempFixturesDir = fileURLToPath(new URL('./_temp-fixtures/', import.meta.url));
|
||||||
#root = '';
|
|
||||||
constructor(root) {
|
|
||||||
super();
|
|
||||||
this.#root = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
#forcePath(p) {
|
|
||||||
if (p instanceof URL) {
|
|
||||||
p = unixify(fileURLToPath(p));
|
|
||||||
} else {
|
|
||||||
p = unixify(p);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFullyResolvedPath(pth) {
|
|
||||||
return npath.posix.join(this.#root, pth);
|
|
||||||
}
|
|
||||||
|
|
||||||
readFile(p, ...args) {
|
|
||||||
return super.readFile(this.#forcePath(p), ...args);
|
|
||||||
}
|
|
||||||
|
|
||||||
existsSync(p) {
|
|
||||||
return super.existsSync(this.#forcePath(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
writeFileFromRootSync(pth, ...rest) {
|
|
||||||
return super.writeFileSync(this.getFullyResolvedPath(pth), ...rest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class VirtualVolumeWithFallback extends VirtualVolume {
|
|
||||||
// Fallback to the real fs
|
|
||||||
readFile(p, ...args) {
|
|
||||||
const cb = args[args.length - 1];
|
|
||||||
const argsMinusCallback = args.slice(0, args.length - 1);
|
|
||||||
return super.readFile(p, ...argsMinusCallback, function (err, data) {
|
|
||||||
if (err) {
|
|
||||||
realFS.readFile(p, ...argsMinusCallback, function (err2, data2) {
|
|
||||||
if (err2) {
|
|
||||||
cb(err);
|
|
||||||
} else {
|
|
||||||
cb(null, data2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cb(null, data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
readFileSync(p, ...args) {
|
|
||||||
try {
|
|
||||||
return super.readFileSync(p, ...args);
|
|
||||||
} catch {
|
|
||||||
return realFS.readFileSync(p, ...args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createFs(json, root, VolumeImpl = VirtualVolume) {
|
|
||||||
if (typeof root !== 'string') {
|
|
||||||
root = unixify(fileURLToPath(root));
|
|
||||||
}
|
|
||||||
|
|
||||||
const structure = {};
|
|
||||||
for (const [key, value] of Object.entries(json)) {
|
|
||||||
const fullpath = npath.posix.join(root, key);
|
|
||||||
structure[fullpath] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fs = new VolumeImpl(root);
|
|
||||||
fs.fromJSON(structure);
|
|
||||||
return fs;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createFsWithFallback(json, root) {
|
|
||||||
return createFs(json, root, VirtualVolumeWithFallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param {import('fs-fixture').FileTree} tree
|
||||||
* @param {import('../../src/core/dev/container').Container} container
|
|
||||||
* @param {typeof import('node:fs')} fs
|
|
||||||
* @param {string} shortPath
|
|
||||||
* @param {'change'} eventType
|
|
||||||
*/
|
*/
|
||||||
export function triggerFSEvent(container, fs, shortPath, eventType) {
|
export async function createFixture(tree) {
|
||||||
container.viteServer.watcher.emit(eventType, fs.getFullyResolvedPath(shortPath));
|
return await _createFixture(
|
||||||
|
{
|
||||||
if (!fileURLToPath(container.settings.config.root).startsWith('/')) {
|
'package.json': '{}',
|
||||||
const drive = fileURLToPath(container.settings.config.root).slice(0, 2);
|
...tree,
|
||||||
container.viteServer.watcher.emit(eventType, drive + fs.getFullyResolvedPath(shortPath));
|
},
|
||||||
}
|
{
|
||||||
|
tempDir: tempFixturesDir,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createRequestAndResponse(reqOptions = {}) {
|
export function createRequestAndResponse(reqOptions = {}) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import { createLoader } from '../../../dist/core/module-loader/index.js';
|
import { createLoader } from '../../../dist/core/module-loader/index.js';
|
||||||
import { createRouteManifest } from '../../../dist/core/routing/index.js';
|
import { createRouteManifest } from '../../../dist/core/routing/index.js';
|
||||||
|
@ -12,13 +11,13 @@ import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createAstroModule,
|
createAstroModule,
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
async function createDevPipeline(overrides = {}) {
|
async function createDevPipeline(overrides = {}, root) {
|
||||||
const settings = overrides.settings ?? (await createBasicSettings({ root: '/' }));
|
const settings = overrides.settings ?? (await createBasicSettings({ root }));
|
||||||
const loader = overrides.loader ?? createLoader();
|
const loader = overrides.loader ?? createLoader();
|
||||||
const manifest = createDevelopmentManifest(settings);
|
const manifest = createDevelopmentManifest(settings);
|
||||||
|
|
||||||
|
@ -28,31 +27,31 @@ async function createDevPipeline(overrides = {}) {
|
||||||
describe('vite-plugin-astro-server', () => {
|
describe('vite-plugin-astro-server', () => {
|
||||||
describe('request', () => {
|
describe('request', () => {
|
||||||
it('renders a request', async () => {
|
it('renders a request', async () => {
|
||||||
const pipeline = await createDevPipeline({
|
const fixture = await createFixture({
|
||||||
loader: createLoader({
|
// Note that the content doesn't matter here because we are using a custom loader.
|
||||||
import(id) {
|
'/src/pages/index.astro': '',
|
||||||
if (id === '\0astro-internal:middleware') {
|
|
||||||
return { onRequest: (_, next) => next() };
|
|
||||||
}
|
|
||||||
const Page = createComponent(() => {
|
|
||||||
return render`<div id="test">testing</div>`;
|
|
||||||
});
|
|
||||||
return createAstroModule(Page);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
const pipeline = await createDevPipeline(
|
||||||
|
{
|
||||||
|
loader: createLoader({
|
||||||
|
import(id) {
|
||||||
|
if (id === '\0astro-internal:middleware') {
|
||||||
|
return { onRequest: (_, next) => next() };
|
||||||
|
}
|
||||||
|
const Page = createComponent(() => {
|
||||||
|
return render`<div id="test">testing</div>`;
|
||||||
|
});
|
||||||
|
return createAstroModule(Page);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
fixture.path,
|
||||||
|
);
|
||||||
const controller = createController({ loader: pipeline.loader });
|
const controller = createController({ loader: pipeline.loader });
|
||||||
const { req, res, text } = createRequestAndResponse();
|
const { req, res, text } = createRequestAndResponse();
|
||||||
const fs = createFs(
|
|
||||||
{
|
|
||||||
// Note that the content doesn't matter here because we are using a custom loader.
|
|
||||||
'/src/pages/index.astro': '',
|
|
||||||
},
|
|
||||||
'/',
|
|
||||||
);
|
|
||||||
const manifestData = createRouteManifest(
|
const manifestData = createRouteManifest(
|
||||||
{
|
{
|
||||||
fsMod: fs,
|
cwd: fixture.path,
|
||||||
settings: pipeline.settings,
|
settings: pipeline.settings,
|
||||||
},
|
},
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
|
@ -82,7 +81,6 @@ describe('vite-plugin-astro-server', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const root = new URL('../../fixtures/api-routes/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/url.astro': `{Astro.request.url}`,
|
'/src/pages/url.astro': `{Astro.request.url}`,
|
||||||
'/src/pages/prerendered.astro': `---
|
'/src/pages/prerendered.astro': `---
|
||||||
|
@ -90,14 +88,13 @@ describe('vite-plugin-astro-server', () => {
|
||||||
---
|
---
|
||||||
{Astro.request.url}`,
|
{Astro.request.url}`,
|
||||||
};
|
};
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import * as assert from 'node:assert/strict';
|
import * as assert from 'node:assert/strict';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { createContainer } from '../../../dist/core/dev/container.js';
|
import { createContainer } from '../../../dist/core/dev/container.js';
|
||||||
import testAdapter from '../../test-adapter.js';
|
import testAdapter from '../../test-adapter.js';
|
||||||
import {
|
import {
|
||||||
createBasicSettings,
|
createBasicSettings,
|
||||||
createFs,
|
createFixture,
|
||||||
createRequestAndResponse,
|
createRequestAndResponse,
|
||||||
defaultLogger,
|
defaultLogger,
|
||||||
} from '../test-utils.js';
|
} from '../test-utils.js';
|
||||||
|
|
||||||
const root = new URL('../../fixtures/api-routes/', import.meta.url);
|
|
||||||
const fileSystem = {
|
const fileSystem = {
|
||||||
'/src/pages/index.js': `export const GET = () => {
|
'/src/pages/index.js': `export const GET = () => {
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
|
@ -51,14 +49,13 @@ describe('endpoints', () => {
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const fs = createFs(fileSystem, root);
|
const fixture = await createFixture(fileSystem);
|
||||||
settings = await createBasicSettings({
|
settings = await createBasicSettings({
|
||||||
root: fileURLToPath(root),
|
root: fixture.path,
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: testAdapter(),
|
adapter: testAdapter(),
|
||||||
});
|
});
|
||||||
container = await createContainer({
|
container = await createContainer({
|
||||||
fs,
|
|
||||||
settings,
|
settings,
|
||||||
logger: defaultLogger,
|
logger: defaultLogger,
|
||||||
});
|
});
|
||||||
|
|
24
patches/fs-fixture@2.4.0.patch
Normal file
24
patches/fs-fixture@2.4.0.patch
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
diff --git a/dist/index.d.mts b/dist/index.d.mts
|
||||||
|
index be5b88e034211892ba079c3c5c5c6f5d5f767cd4..55dcc0e99c66719d5fa68d4713b02c1919deae19 100644
|
||||||
|
--- a/dist/index.d.mts
|
||||||
|
+++ b/dist/index.d.mts
|
||||||
|
@@ -61,6 +61,10 @@ type Api = ApiBase & {
|
||||||
|
type FileTree = {
|
||||||
|
[path: string]: string | FileTree | ((api: Api) => string | Symlink);
|
||||||
|
};
|
||||||
|
-declare const createFixture: (source?: string | FileTree) => Promise<FsFixture>;
|
||||||
|
+type CreateFixtureOptions = {
|
||||||
|
+ // An absolute path to a different directory than `os.tmpdir()`
|
||||||
|
+ tempDir?: string
|
||||||
|
+}
|
||||||
|
+declare const createFixture: (source?: string | FileTree, opts?: CreateFixtureOptions) => Promise<FsFixture>;
|
||||||
|
|
||||||
|
-export { type FileTree, FsFixture, createFixture };
|
||||||
|
+export { type FileTree, FsFixture, CreateFixtureOptions, createFixture };
|
||||||
|
diff --git a/dist/index.mjs b/dist/index.mjs
|
||||||
|
index cd6cab3beebf3f38fe4f1e2a9c58aff2b87258f7..ad24d852a357fd582f9e83ac20cb73bfbcb9bfc0 100755
|
||||||
|
--- a/dist/index.mjs
|
||||||
|
+++ b/dist/index.mjs
|
||||||
|
@@ -1 +1 @@
|
||||||
|
-import s from"fs/promises";import o from"path";import y from"fs";import m from"os";typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{configurable:!1,enumerable:!1,writable:!1,value:Symbol.for("asyncDispose")});class w{path;constructor(t){this.path=t}getPath(...t){return o.join(this.path,...t)}exists(t=""){return s.access(this.getPath(t)).then(()=>!0,()=>!1)}rm(t=""){return s.rm(this.getPath(t),{recursive:!0,force:!0})}writeFile(t,r){return s.writeFile(this.getPath(t),r)}writeJson(t,r){return this.writeFile(t,JSON.stringify(r,null,2))}readFile(t,r){return s.readFile(this.getPath(t),r)}async[Symbol.asyncDispose](){await this.rm()}}const g=y.realpathSync(m.tmpdir()),b=`fs-fixture-${Date.now()}`;let l=0;const P=()=>(l+=1,l);class h{target;type;path;constructor(t,r){this.target=t,this.type=r}}const u=(i,t,r)=>{const e=[];for(const n in i){if(!Object.hasOwn(i,n))continue;const c=o.join(t,n);let a=i[n];if(typeof a=="function"){const f=Object.assign(Object.create(r),{filePath:c}),p=a(f);if(p instanceof h){p.path=c,e.push(p);continue}else a=p}typeof a=="string"?e.push({path:c,content:a}):e.push(...u(a,c,r))}return e},d=async i=>{const t=o.join(g,`${b}-${P()}/`);if(await s.mkdir(t,{recursive:!0}),i){if(typeof i=="string")await s.cp(i,t,{recursive:!0});else if(typeof i=="object"){const r={fixturePath:t,getPath:(...e)=>o.join(t,...e),symlink:(e,n)=>new h(e,n)};await Promise.all(u(i,t,r).map(async e=>{await s.mkdir(o.dirname(e.path),{recursive:!0}),e instanceof h?await s.symlink(e.target,e.path,e.type):await s.writeFile(e.path,e.content)}))}}return new w(t)};export{d as createFixture};
|
||||||
|
+import s from"fs/promises";import o from"path";import y from"fs";import m from"os";typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{configurable:!1,enumerable:!1,writable:!1,value:Symbol.for("asyncDispose")});class w{path;constructor(t){this.path=t}getPath(...t){return o.join(this.path,...t)}exists(t=""){return s.access(this.getPath(t)).then(()=>!0,()=>!1)}rm(t=""){return s.rm(this.getPath(t),{recursive:!0,force:!0})}writeFile(t,r){return s.writeFile(this.getPath(t),r)}writeJson(t,r){return this.writeFile(t,JSON.stringify(r,null,2))}readFile(t,r){return s.readFile(this.getPath(t),r)}async[Symbol.asyncDispose](){await this.rm()}}const g=y.realpathSync(m.tmpdir()),b=`fs-fixture-${Date.now()}`;let l=0;const P=()=>(l+=1,l);class h{target;type;path;constructor(t,r){this.target=t,this.type=r}}const u=(i,t,r)=>{const e=[];for(const n in i){if(!Object.hasOwn(i,n))continue;const c=o.join(t,n);let a=i[n];if(typeof a=="function"){const f=Object.assign(Object.create(r),{filePath:c}),p=a(f);if(p instanceof h){p.path=c,e.push(p);continue}else a=p}typeof a=="string"?e.push({path:c,content:a}):e.push(...u(a,c,r))}return e},d=async (i, opts)=>{const t=o.join(opts?.tempDir ?? g,`${b}-${P()}/`);if(await s.mkdir(t,{recursive:!0}),i){if(typeof i=="string")await s.cp(i,t,{recursive:!0});else if(typeof i=="object"){const r={fixturePath:t,getPath:(...e)=>o.join(t,...e),symlink:(e,n)=>new h(e,n)};await Promise.all(u(i,t,r).map(async e=>{await s.mkdir(o.dirname(e.path),{recursive:!0}),e instanceof h?await s.symlink(e.target,e.path,e.type):await s.writeFile(e.path,e.content)}))}}return new w(t)};export{d as createFixture};
|
103
pnpm-lock.yaml
103
pnpm-lock.yaml
|
@ -4,6 +4,11 @@ settings:
|
||||||
autoInstallPeers: false
|
autoInstallPeers: false
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
patchedDependencies:
|
||||||
|
fs-fixture@2.4.0:
|
||||||
|
hash: hvkuaks2ic76pdflr3iifgi4ku
|
||||||
|
path: patches/fs-fixture@2.4.0.patch
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
|
@ -703,15 +708,15 @@ importers:
|
||||||
expect-type:
|
expect-type:
|
||||||
specifier: ^1.1.0
|
specifier: ^1.1.0
|
||||||
version: 1.1.0
|
version: 1.1.0
|
||||||
|
fs-fixture:
|
||||||
|
specifier: ^2.4.0
|
||||||
|
version: 2.4.0(patch_hash=hvkuaks2ic76pdflr3iifgi4ku)
|
||||||
mdast-util-mdx:
|
mdast-util-mdx:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
mdast-util-mdx-jsx:
|
mdast-util-mdx-jsx:
|
||||||
specifier: ^3.1.3
|
specifier: ^3.1.3
|
||||||
version: 3.1.3
|
version: 3.1.3
|
||||||
memfs:
|
|
||||||
specifier: ^4.14.0
|
|
||||||
version: 4.14.0
|
|
||||||
node-mocks-http:
|
node-mocks-http:
|
||||||
specifier: ^1.16.1
|
specifier: ^1.16.1
|
||||||
version: 1.16.1(@types/node@18.19.50)
|
version: 1.16.1(@types/node@18.19.50)
|
||||||
|
@ -2665,12 +2670,6 @@ importers:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../..
|
version: link:../../..
|
||||||
|
|
||||||
packages/astro/test/fixtures/content-mixed-errors:
|
|
||||||
dependencies:
|
|
||||||
astro:
|
|
||||||
specifier: workspace:*
|
|
||||||
version: link:../../..
|
|
||||||
|
|
||||||
packages/astro/test/fixtures/content-ssr-integration:
|
packages/astro/test/fixtures/content-ssr-integration:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/mdx':
|
'@astrojs/mdx':
|
||||||
|
@ -4172,6 +4171,15 @@ importers:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../../..
|
version: link:../../..
|
||||||
|
|
||||||
|
packages/astro/test/units/_temp-fixtures:
|
||||||
|
dependencies:
|
||||||
|
'@astrojs/mdx':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../../../integrations/mdx
|
||||||
|
astro:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../..
|
||||||
|
|
||||||
packages/create-astro:
|
packages/create-astro:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@astrojs/cli-kit':
|
'@astrojs/cli-kit':
|
||||||
|
@ -6528,24 +6536,6 @@ packages:
|
||||||
resolution: {integrity: sha512-n5JEf16Wr4mdkRMZ8wMP/wN9/sHmTjRPbouXjJH371mZ2LEGDl72t8tEsMRNFerQN/QJtivOxqK1frdGa4QK5Q==}
|
resolution: {integrity: sha512-n5JEf16Wr4mdkRMZ8wMP/wN9/sHmTjRPbouXjJH371mZ2LEGDl72t8tEsMRNFerQN/QJtivOxqK1frdGa4QK5Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
'@jsonjoy.com/base64@1.1.2':
|
|
||||||
resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==}
|
|
||||||
engines: {node: '>=10.0'}
|
|
||||||
peerDependencies:
|
|
||||||
tslib: '2'
|
|
||||||
|
|
||||||
'@jsonjoy.com/json-pack@1.1.0':
|
|
||||||
resolution: {integrity: sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==}
|
|
||||||
engines: {node: '>=10.0'}
|
|
||||||
peerDependencies:
|
|
||||||
tslib: '2'
|
|
||||||
|
|
||||||
'@jsonjoy.com/util@1.3.0':
|
|
||||||
resolution: {integrity: sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==}
|
|
||||||
engines: {node: '>=10.0'}
|
|
||||||
peerDependencies:
|
|
||||||
tslib: '2'
|
|
||||||
|
|
||||||
'@libsql/client@0.14.0':
|
'@libsql/client@0.14.0':
|
||||||
resolution: {integrity: sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q==}
|
resolution: {integrity: sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q==}
|
||||||
|
|
||||||
|
@ -8274,6 +8264,10 @@ packages:
|
||||||
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
|
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
|
||||||
engines: {node: '>=6 <7 || >=8'}
|
engines: {node: '>=6 <7 || >=8'}
|
||||||
|
|
||||||
|
fs-fixture@2.4.0:
|
||||||
|
resolution: {integrity: sha512-aFoTWGj288IEOdXBeesdcbdMvRtExbqpOp1SCjE3nRdlT7vBBCD6bf76C9FCq8/6pIPSo56P7+HeT9zT/n8rMA==}
|
||||||
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
||||||
fsevents@2.3.2:
|
fsevents@2.3.2:
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
|
@ -8475,10 +8469,6 @@ packages:
|
||||||
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
||||||
engines: {node: '>=16.17.0'}
|
engines: {node: '>=16.17.0'}
|
||||||
|
|
||||||
hyperdyperid@1.2.0:
|
|
||||||
resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==}
|
|
||||||
engines: {node: '>=10.18'}
|
|
||||||
|
|
||||||
hyperid@3.3.0:
|
hyperid@3.3.0:
|
||||||
resolution: {integrity: sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ==}
|
resolution: {integrity: sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ==}
|
||||||
|
|
||||||
|
@ -8924,10 +8914,6 @@ packages:
|
||||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
memfs@4.14.0:
|
|
||||||
resolution: {integrity: sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==}
|
|
||||||
engines: {node: '>= 4.0.0'}
|
|
||||||
|
|
||||||
merge-anything@5.1.7:
|
merge-anything@5.1.7:
|
||||||
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
|
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
|
||||||
engines: {node: '>=12.13'}
|
engines: {node: '>=12.13'}
|
||||||
|
@ -10243,12 +10229,6 @@ packages:
|
||||||
thenify@3.3.1:
|
thenify@3.3.1:
|
||||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||||
|
|
||||||
thingies@1.21.0:
|
|
||||||
resolution: {integrity: sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==}
|
|
||||||
engines: {node: '>=10.18'}
|
|
||||||
peerDependencies:
|
|
||||||
tslib: ^2
|
|
||||||
|
|
||||||
timestring@6.0.0:
|
timestring@6.0.0:
|
||||||
resolution: {integrity: sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==}
|
resolution: {integrity: sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -10302,12 +10282,6 @@ packages:
|
||||||
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
|
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
tree-dump@1.0.2:
|
|
||||||
resolution: {integrity: sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==}
|
|
||||||
engines: {node: '>=10.0'}
|
|
||||||
peerDependencies:
|
|
||||||
tslib: '2'
|
|
||||||
|
|
||||||
trim-lines@3.0.1:
|
trim-lines@3.0.1:
|
||||||
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
|
||||||
|
|
||||||
|
@ -11997,22 +11971,6 @@ snapshots:
|
||||||
|
|
||||||
'@jsdevtools/rehype-toc@3.0.2': {}
|
'@jsdevtools/rehype-toc@3.0.2': {}
|
||||||
|
|
||||||
'@jsonjoy.com/base64@1.1.2(tslib@2.7.0)':
|
|
||||||
dependencies:
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
'@jsonjoy.com/json-pack@1.1.0(tslib@2.7.0)':
|
|
||||||
dependencies:
|
|
||||||
'@jsonjoy.com/base64': 1.1.2(tslib@2.7.0)
|
|
||||||
'@jsonjoy.com/util': 1.3.0(tslib@2.7.0)
|
|
||||||
hyperdyperid: 1.2.0
|
|
||||||
thingies: 1.21.0(tslib@2.7.0)
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
'@jsonjoy.com/util@1.3.0(tslib@2.7.0)':
|
|
||||||
dependencies:
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
'@libsql/client@0.14.0':
|
'@libsql/client@0.14.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@libsql/core': 0.14.0
|
'@libsql/core': 0.14.0
|
||||||
|
@ -13833,6 +13791,8 @@ snapshots:
|
||||||
jsonfile: 4.0.0
|
jsonfile: 4.0.0
|
||||||
universalify: 0.1.2
|
universalify: 0.1.2
|
||||||
|
|
||||||
|
fs-fixture@2.4.0(patch_hash=hvkuaks2ic76pdflr3iifgi4ku): {}
|
||||||
|
|
||||||
fsevents@2.3.2:
|
fsevents@2.3.2:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
@ -14145,8 +14105,6 @@ snapshots:
|
||||||
|
|
||||||
human-signals@5.0.0: {}
|
human-signals@5.0.0: {}
|
||||||
|
|
||||||
hyperdyperid@1.2.0: {}
|
|
||||||
|
|
||||||
hyperid@3.3.0:
|
hyperid@3.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer: 5.7.1
|
buffer: 5.7.1
|
||||||
|
@ -14709,13 +14667,6 @@ snapshots:
|
||||||
|
|
||||||
media-typer@0.3.0: {}
|
media-typer@0.3.0: {}
|
||||||
|
|
||||||
memfs@4.14.0:
|
|
||||||
dependencies:
|
|
||||||
'@jsonjoy.com/json-pack': 1.1.0(tslib@2.7.0)
|
|
||||||
'@jsonjoy.com/util': 1.3.0(tslib@2.7.0)
|
|
||||||
tree-dump: 1.0.2(tslib@2.7.0)
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
merge-anything@5.1.7:
|
merge-anything@5.1.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-what: 4.1.16
|
is-what: 4.1.16
|
||||||
|
@ -16344,10 +16295,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
|
|
||||||
thingies@1.21.0(tslib@2.7.0):
|
|
||||||
dependencies:
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
timestring@6.0.0: {}
|
timestring@6.0.0: {}
|
||||||
|
|
||||||
tinybench@2.9.0: {}
|
tinybench@2.9.0: {}
|
||||||
|
@ -16387,10 +16334,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
tree-dump@1.0.2(tslib@2.7.0):
|
|
||||||
dependencies:
|
|
||||||
tslib: 2.7.0
|
|
||||||
|
|
||||||
trim-lines@3.0.1: {}
|
trim-lines@3.0.1: {}
|
||||||
|
|
||||||
trough@2.2.0: {}
|
trough@2.2.0: {}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
packages:
|
packages:
|
||||||
- 'packages/**/*'
|
- 'packages/**/*'
|
||||||
|
- 'packages/astro/test/units/_temp-fixtures'
|
||||||
- 'examples/**/*'
|
- 'examples/**/*'
|
||||||
- 'smoke/**/*'
|
- 'smoke/**/*'
|
||||||
- 'scripts'
|
- 'scripts'
|
||||||
- 'benchmark'
|
- 'benchmark'
|
||||||
- 'benchmark/packages/*'
|
- 'benchmark/packages/*'
|
||||||
# Below excludes are only for Turbo because it doesn't respect gitignore like pnpm does
|
# Below excludes are only for Turbo because it doesn't respect gitignore like pnpm does
|
||||||
|
- '!packages/astro/test/units/_temp-fixtures/*'
|
||||||
- '!**/.vercel/**'
|
- '!**/.vercel/**'
|
||||||
|
|
|
@ -25,6 +25,8 @@ export default async function test() {
|
||||||
timeout: { type: 'string', alias: 't' },
|
timeout: { type: 'string', alias: 't' },
|
||||||
// Test setup file
|
// Test setup file
|
||||||
setup: { type: 'string', alias: 's' },
|
setup: { type: 'string', alias: 's' },
|
||||||
|
// Test teardown file
|
||||||
|
teardown: { type: 'string' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,6 +61,10 @@ export default async function test() {
|
||||||
files.push(tempTestFile);
|
files.push(tempTestFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const teardownModule = args.values.teardown
|
||||||
|
? await import(pathToFileURL(path.resolve(args.values.teardown)).toString())
|
||||||
|
: undefined;
|
||||||
|
|
||||||
// https://nodejs.org/api/test.html#runoptions
|
// https://nodejs.org/api/test.html#runoptions
|
||||||
run({
|
run({
|
||||||
files,
|
files,
|
||||||
|
@ -74,6 +80,10 @@ export default async function test() {
|
||||||
// so we set it here manually
|
// so we set it here manually
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
})
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
const testPassed = process.exitCode === 0 || process.exitCode === undefined;
|
||||||
|
teardownModule?.default(testPassed);
|
||||||
|
})
|
||||||
.pipe(new spec())
|
.pipe(new spec())
|
||||||
.pipe(process.stdout);
|
.pipe(process.stdout);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue