summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2024-10-15 15:34:42 +0800
committerGravatar GitHub <noreply@github.com> 2024-10-15 15:34:42 +0800
commit64bb796c0fee551b8b2349b5246946f60080565b (patch)
tree6caff13adaa98b6cb46901a433f332a25da4ee63
parent5ab2d980aae8c92e71e01a8bd21c8d771e576085 (diff)
downloadastro-64bb796c0fee551b8b2349b5246946f60080565b.tar.gz
astro-64bb796c0fee551b8b2349b5246946f60080565b.tar.zst
astro-64bb796c0fee551b8b2349b5246946f60080565b.zip
Use real filesystem for unit testing (#12172)
-rw-r--r--.gitignore3
-rw-r--r--biome.jsonc1
-rw-r--r--package.json3
-rw-r--r--packages/astro/package.json9
-rw-r--r--packages/astro/src/vite-plugin-astro-server/plugin.ts3
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/astro.config.mjs4
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/package.json16
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/src/content/authors/placeholder.json3
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/src/content/blog/placeholder.md3
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/src/pages/authors.astro10
-rw-r--r--packages/astro/test/fixtures/content-mixed-errors/src/pages/blog.astro7
-rw-r--r--packages/astro/test/units/_temp-fixtures/package.json8
-rw-r--r--packages/astro/test/units/config/format.test.js20
-rw-r--r--packages/astro/test/units/content-collections/frontmatter.test.js36
-rw-r--r--packages/astro/test/units/correct-path.js70
-rw-r--r--packages/astro/test/units/dev/base.test.js52
-rw-r--r--packages/astro/test/units/dev/collections-mixed-content-errors.test.js205
-rw-r--r--packages/astro/test/units/dev/collections-renderentry.test.js97
-rw-r--r--packages/astro/test/units/dev/dev.test.js130
-rw-r--r--packages/astro/test/units/dev/head-injection.test.js13
-rw-r--r--packages/astro/test/units/dev/hydration.test.js17
-rw-r--r--packages/astro/test/units/dev/restart.test.js161
-rw-r--r--packages/astro/test/units/render/chunk.test.js17
-rw-r--r--packages/astro/test/units/render/components.test.js39
-rw-r--r--packages/astro/test/units/routing/endpoints.test.js8
-rw-r--r--packages/astro/test/units/routing/manifest.test.js229
-rw-r--r--packages/astro/test/units/routing/route-matching.test.js11
-rw-r--r--packages/astro/test/units/routing/route-sanitization.test.js9
-rw-r--r--packages/astro/test/units/routing/trailing-slash.test.js9
-rw-r--r--packages/astro/test/units/runtime/endpoints.test.js8
-rw-r--r--packages/astro/test/units/teardown.js19
-rw-r--r--packages/astro/test/units/test-utils.js109
-rw-r--r--packages/astro/test/units/vite-plugin-astro-server/request.test.js51
-rw-r--r--packages/astro/test/units/vite-plugin-astro-server/response.test.js9
-rw-r--r--patches/fs-fixture@2.4.0.patch24
-rw-r--r--pnpm-lock.yaml103
-rw-r--r--pnpm-workspace.yaml2
-rw-r--r--scripts/cmd/test.js10
38 files changed, 583 insertions, 945 deletions
diff --git a/.gitignore b/.gitignore
index 8e6d78354..d6a28ec1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,7 +21,8 @@ package-lock.json
packages/astro/src/**/*.prebuilt.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/
# exclude IntelliJ/WebStorm stuff
diff --git a/biome.jsonc b/biome.jsonc
index a94930143..227f37a08 100644
--- a/biome.jsonc
+++ b/biome.jsonc
@@ -6,6 +6,7 @@
"**/dist/**",
"**/smoke/**",
"**/fixtures/**",
+ "**/_temp-fixtures/**",
"**/vendor/**",
"**/.vercel/**",
],
diff --git a/package.json b/package.json
index 7c2919886..683384edf 100644
--- a/package.json
+++ b/package.json
@@ -87,6 +87,9 @@
"allowAny": [
"astro"
]
+ },
+ "patchedDependencies": {
+ "fs-fixture@2.4.0": "patches/fs-fixture@2.4.0.patch"
}
}
}
diff --git a/packages/astro/package.json b/packages/astro/package.json
index 09e71a830..054bc92f3 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -112,14 +112,15 @@
"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",
"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:match": "pnpm run test:node --match",
+ "test": "pnpm run test:unit && pnpm run test:integration && pnpm run test:types",
+ "test:match": "astro-scripts test \"test/**/*.test.js\" --match",
"test:e2e": "pnpm test:e2e:chrome && pnpm test:e2e:firefox",
"test:e2e:match": "playwright test -g",
"test:e2e:chrome": "playwright test",
"test:e2e:firefox": "playwright test --config playwright.firefox.config.js",
"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": {
"@astrojs/compiler": "^2.10.3",
@@ -210,9 +211,9 @@
"eol": "^0.10.0",
"execa": "^8.0.1",
"expect-type": "^1.1.0",
+ "fs-fixture": "^2.4.0",
"mdast-util-mdx": "^3.0.0",
"mdast-util-mdx-jsx": "^3.1.3",
- "memfs": "^4.14.0",
"node-mocks-http": "^1.16.1",
"parse-srcset": "^1.0.2",
"rehype-autolink-headings": "^7.1.0",
diff --git a/packages/astro/src/vite-plugin-astro-server/plugin.ts b/packages/astro/src/vite-plugin-astro-server/plugin.ts
index 3b75a3843..55f12216d 100644
--- a/packages/astro/src/vite-plugin-astro-server/plugin.ts
+++ b/packages/astro/src/vite-plugin-astro-server/plugin.ts
@@ -77,6 +77,9 @@ export default function createVitePluginAstroServer({
}
process.on('unhandledRejection', handleUnhandledRejection);
+ viteServer.httpServer?.on('close', () => {
+ process.off('unhandledRejection', handleUnhandledRejection);
+ });
return () => {
// Push this middleware to the front of the stack so that it can intercept responses.
diff --git a/packages/astro/test/fixtures/content-mixed-errors/astro.config.mjs b/packages/astro/test/fixtures/content-mixed-errors/astro.config.mjs
deleted file mode 100644
index 882e6515a..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/astro.config.mjs
+++ /dev/null
@@ -1,4 +0,0 @@
-import { defineConfig } from 'astro/config';
-
-// https://astro.build/config
-export default defineConfig({});
diff --git a/packages/astro/test/fixtures/content-mixed-errors/package.json b/packages/astro/test/fixtures/content-mixed-errors/package.json
deleted file mode 100644
index d90bfabda..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/package.json
+++ /dev/null
@@ -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:*"
- }
-}
diff --git a/packages/astro/test/fixtures/content-mixed-errors/src/content/authors/placeholder.json b/packages/astro/test/fixtures/content-mixed-errors/src/content/authors/placeholder.json
deleted file mode 100644
index 64ae1c04c..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/src/content/authors/placeholder.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "name": "Placeholder"
-}
diff --git a/packages/astro/test/fixtures/content-mixed-errors/src/content/blog/placeholder.md b/packages/astro/test/fixtures/content-mixed-errors/src/content/blog/placeholder.md
deleted file mode 100644
index f7f65691b..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/src/content/blog/placeholder.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Placeholder post
----
diff --git a/packages/astro/test/fixtures/content-mixed-errors/src/pages/authors.astro b/packages/astro/test/fixtures/content-mixed-errors/src/pages/authors.astro
deleted file mode 100644
index 8352a3d27..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/src/pages/authors.astro
+++ /dev/null
@@ -1,10 +0,0 @@
----
-import { getCollection } from 'astro:content';
-try {
- await getCollection('authors')
-} catch (e) {
- return e
-}
----
-
-<h1>Worked</h1>
diff --git a/packages/astro/test/fixtures/content-mixed-errors/src/pages/blog.astro b/packages/astro/test/fixtures/content-mixed-errors/src/pages/blog.astro
deleted file mode 100644
index 0d5d2836e..000000000
--- a/packages/astro/test/fixtures/content-mixed-errors/src/pages/blog.astro
+++ /dev/null
@@ -1,7 +0,0 @@
----
-import { getCollection } from 'astro:content';
-
-await getCollection('blog')
----
-
-<h1>Worked</h1>
diff --git a/packages/astro/test/units/_temp-fixtures/package.json b/packages/astro/test/units/_temp-fixtures/package.json
new file mode 100644
index 000000000..3ecea0bfe
--- /dev/null
+++ b/packages/astro/test/units/_temp-fixtures/package.json
@@ -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:*"
+ }
+}
diff --git a/packages/astro/test/units/config/format.test.js b/packages/astro/test/units/config/format.test.js
index 7b0c88d73..66938a03a 100644
--- a/packages/astro/test/units/config/format.test.js
+++ b/packages/astro/test/units/config/format.test.js
@@ -1,25 +1,19 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
-import { createFs, runInContainer } from '../test-utils.js';
-
-const root = new URL('../../fixtures/tailwindcss-ts/', import.meta.url);
+import { createFixture, runInContainer } from '../test-utils.js';
describe('Astro config formats', () => {
it('An mjs config can import TypeScript modules', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': ``,
- '/src/stuff.ts': `export default 'works';`,
- '/astro.config.mjs': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': ``,
+ '/src/stuff.ts': `export default 'works';`,
+ '/astro.config.mjs': `\
import stuff from './src/stuff.ts';
export default {}
`,
- },
- root,
- );
+ });
- await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, () => {
+ await runInContainer({ inlineConfig: { root: fixture.path } }, () => {
assert.equal(
true,
true,
diff --git a/packages/astro/test/units/content-collections/frontmatter.test.js b/packages/astro/test/units/content-collections/frontmatter.test.js
index 2a3cd31ec..4f587a90f 100644
--- a/packages/astro/test/units/content-collections/frontmatter.test.js
+++ b/packages/astro/test/units/content-collections/frontmatter.test.js
@@ -1,33 +1,16 @@
-import nodeFS from 'node:fs';
-import path from 'node:path';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { attachContentServerListeners } from '../../../dist/content/index.js';
-import { createFs, runInContainer, triggerFSEvent } 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'),
- };
-}
+import { createFixture, runInContainer } from '../test-utils.js';
describe('frontmatter', () => {
it('errors in content/ does not crash server', async () => {
- const fs = createFs(
- {
- ...getTypesDts(),
- '/src/content/posts/blog.md': `
+ const fixture = await createFixture({
+ '/src/content/posts/blog.md': `\
---
title: One
---
`,
- '/src/content/config.ts': `
+ '/src/content/config.ts': `\
import { defineCollection, z } from 'astro:content';
const posts = defineCollection({
@@ -38,7 +21,7 @@ describe('frontmatter', () => {
posts
};
`,
- '/src/pages/index.astro': `
+ '/src/pages/index.astro': `\
---
---
<html>
@@ -48,14 +31,12 @@ describe('frontmatter', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
- await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
+ await runInContainer({ inlineConfig: { root: fixture.path } }, async (container) => {
await attachContentServerListeners(container);
- fs.writeFileFromRootSync(
+ await fixture.writeFile(
'/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));
// Note, if we got here, it didn't crash
});
diff --git a/packages/astro/test/units/correct-path.js b/packages/astro/test/units/correct-path.js
deleted file mode 100644
index 026baeaf6..000000000
--- a/packages/astro/test/units/correct-path.js
+++ /dev/null
@@ -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(/^\\\\\?\\.:\\/, '\\'));
-}
diff --git a/packages/astro/test/units/dev/base.test.js b/packages/astro/test/units/dev/base.test.js
index e625df478..f230ad563 100644
--- a/packages/astro/test/units/dev/base.test.js
+++ b/packages/astro/test/units/dev/base.test.js
@@ -1,26 +1,19 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
-import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
describe('base configuration', () => {
describe('with trailingSlash: "never"', () => {
describe('index route', () => {
it('Requests that include a trailing slash 404', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>testing</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>testing</h1>`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/docs',
trailingSlash: 'never',
},
@@ -38,18 +31,15 @@ describe('base configuration', () => {
});
it('Requests that exclude a trailing slash 200', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>testing</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>testing</h1>`,
+ });
await runInContainer(
{
fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/docs',
trailingSlash: 'never',
},
@@ -69,18 +59,14 @@ describe('base configuration', () => {
describe('sub route', () => {
it('Requests that include a trailing slash 404', async () => {
- const fs = createFs(
- {
- '/src/pages/sub/index.astro': `<h1>testing</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/sub/index.astro': `<h1>testing</h1>`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/docs',
trailingSlash: 'never',
},
@@ -98,18 +84,14 @@ describe('base configuration', () => {
});
it('Requests that exclude a trailing slash 200', async () => {
- const fs = createFs(
- {
- '/src/pages/sub/index.astro': `<h1>testing</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/sub/index.astro': `<h1>testing</h1>`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/docs',
trailingSlash: 'never',
},
diff --git a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
index 3417650fc..9da0c776f 100644
--- a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
+++ b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
@@ -1,129 +1,146 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
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({ fs }) {
+async function sync(root) {
try {
- await _sync(
- {
- root: fileURLToPath(root),
- logLevel: 'silent',
- },
- {
- fs,
- },
- );
+ await _sync({
+ root,
+ logLevel: 'silent',
+ });
return 0;
- } catch (_) {
+ } catch {
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', () => {
it('raises "mixed content" error when content in data collection', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/authors/ben.md': `---
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/authors/ben.md': `\
+---
name: Ben
---
-# Ben`,
- '/src/content/authors/tony.json': `{ "name": "Tony" }`,
- '/src/content/config.ts': `
-
- import { z, defineCollection } from 'astro:content';
-
- const authors = defineCollection({
- type: 'data',
- schema: z.object({
- name: z.string(),
- }),
- });
+# Ben
+`,
+ '/src/content/authors/tony.json': `{ "name": "Tony" }`,
+ '/src/content/config.ts': `\
+import { z, defineCollection } from 'astro:content';
+
+const authors = defineCollection({
+ type: 'data',
+ schema: z.object({
+ name: z.string(),
+ }),
+});
- export const collections = { authors };`,
- },
- root,
- );
+export const collections = { authors };
+`,
+ });
- assert.equal(await sync({ fs }), 1);
+ assert.equal(await sync(fixture.path), 1);
});
it('raises "mixed content" error when data in content collection', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/blog/post.md': `---
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/blog/post.md': `\
+---
title: Post
---
-# Post`,
- '/src/content/blog/post.yaml': `title: YAML Post`,
- '/src/content/config.ts': `
-
- import { z, defineCollection } from 'astro:content';
-
- const blog = defineCollection({
- type: 'content',
- schema: z.object({
- title: z.string(),
- }),
- });
+# Post
+`,
+ '/src/content/blog/post.yaml': `title: YAML Post`,
+ '/src/content/config.ts': `\
+import { z, defineCollection } from 'astro:content';
+
+const blog = defineCollection({
+ type: 'content',
+ schema: z.object({
+ title: z.string(),
+ }),
+});
- export const collections = { blog };`,
- },
- root,
- );
+export const collections = { blog };
+`,
+ });
- assert.equal(await sync({ fs }), 1);
+ assert.equal(await sync(fixture.path), 1);
});
it('raises error when data collection configured as content collection', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/banners/welcome.json': `{ "src": "/example", "alt": "Welcome" }`,
- '/src/content/config.ts': `
-
- import { z, defineCollection } from 'astro:content';
-
- const banners = defineCollection({
- schema: z.object({
- src: z.string(),
- alt: z.string(),
- }),
- });
-
- export const collections = { banners };`,
- },
- root,
- );
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/banners/welcome.json': `{ "src": "/example", "alt": "Welcome" }`,
+ '/src/content/config.ts': `\
+import { z, defineCollection } from 'astro:content';
+
+const banners = defineCollection({
+ schema: z.object({
+ src: z.string(),
+ alt: z.string(),
+ }),
+});
+
+export const collections = { banners };
+`,
+ });
- assert.equal(await sync({ fs }), 1);
+ assert.equal(await sync(fixture.path), 1);
});
it('does not raise error for empty collection with config', async () => {
- const fs = createFsWithFallback(
- {
- // Add placeholder to ensure directory exists
- '/src/content/i18n/_placeholder.txt': 'Need content here',
- '/src/content/config.ts': `
- import { z, defineCollection } from 'astro:content';
-
- const i18n = defineCollection({
- type: 'data',
- schema: z.object({
- greeting: z.string(),
- }),
- });
-
- export const collections = { i18n };`,
- },
- root,
- );
+ const fixture = await createFixture({
+ ...baseFileTree,
+ // Add placeholder to ensure directory exists
+ '/src/content/i18n/_placeholder.txt': 'Need content here',
+ '/src/content/config.ts': `\
+import { z, defineCollection } from 'astro:content';
+
+const i18n = defineCollection({
+ type: 'data',
+ schema: z.object({
+ greeting: z.string(),
+ }),
+});
+
+export const collections = { i18n };
+`,
+ });
- const res = await sync({ fs });
- assert.equal(res, 0);
+ assert.equal(await sync(fixture.path), 0);
});
});
diff --git a/packages/astro/test/units/dev/collections-renderentry.test.js b/packages/astro/test/units/dev/collections-renderentry.test.js
index 082cd6b2f..6bd906c9c 100644
--- a/packages/astro/test/units/dev/collections-renderentry.test.js
+++ b/packages/astro/test/units/dev/collections-renderentry.test.js
@@ -1,12 +1,39 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
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} */
async function runInContainerWithContentListeners(params, callback) {
@@ -18,9 +45,9 @@ async function runInContainerWithContentListeners(params, callback) {
describe('Content Collections - render()', () => {
it('can be called in a page component', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/config.ts': `
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/config.ts': `
import { z, defineCollection } from 'astro:content';
const blog = defineCollection({
@@ -32,7 +59,7 @@ describe('Content Collections - render()', () => {
export const collections = { blog };
`,
- '/src/pages/index.astro': `
+ '/src/pages/index.astro': `
---
import { getCollection } from 'astro:content';
const blog = await getCollection('blog');
@@ -47,15 +74,12 @@ describe('Content Collections - render()', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
await runInContainerWithContentListeners(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
@@ -79,9 +103,9 @@ describe('Content Collections - render()', () => {
});
it('can be used in a layout component', async () => {
- const fs = createFsWithFallback(
- {
- '/src/components/Layout.astro': `
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/components/Layout.astro': `
---
import { getCollection } from 'astro:content';
const blog = await getCollection('blog');
@@ -99,7 +123,7 @@ describe('Content Collections - render()', () => {
</html>
`,
- '/src/pages/index.astro': `
+ '/src/pages/index.astro': `
---
import Layout from '../components/Layout.astro';
---
@@ -107,15 +131,12 @@ describe('Content Collections - render()', () => {
<h1 slot="title">Index page</h2>
</Layout>
`,
- },
- root,
- );
+ });
await runInContainerWithContentListeners(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
@@ -139,9 +160,9 @@ describe('Content Collections - render()', () => {
});
it('can be used in a slot', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/config.ts': `
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/config.ts': `
import { z, defineCollection } from 'astro:content';
const blog = defineCollection({
@@ -153,7 +174,7 @@ describe('Content Collections - render()', () => {
export const collections = { blog };
`,
- '/src/components/Layout.astro': `
+ '/src/components/Layout.astro': `
<html>
<head></head>
<body>
@@ -164,7 +185,7 @@ describe('Content Collections - render()', () => {
</body>
</html>
`,
- '/src/pages/index.astro': `
+ '/src/pages/index.astro': `
---
import Layout from '../components/Layout.astro';
import { getCollection } from 'astro:content';
@@ -177,15 +198,12 @@ describe('Content Collections - render()', () => {
<Content slot="main" />
</Layout>
`,
- },
- root,
- );
+ });
await runInContainerWithContentListeners(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
@@ -209,9 +227,9 @@ describe('Content Collections - render()', () => {
});
it('can be called from any js/ts file', async () => {
- const fs = createFsWithFallback(
- {
- '/src/content/config.ts': `
+ const fixture = await createFixture({
+ ...baseFileTree,
+ '/src/content/config.ts': `
import { z, defineCollection } from 'astro:content';
const blog = defineCollection({
@@ -223,7 +241,7 @@ describe('Content Collections - render()', () => {
export const collections = { blog };
`,
- '/src/launch-week.ts': `
+ '/src/launch-week.ts': `
import { getCollection } from 'astro:content';
export let Content;
@@ -234,7 +252,7 @@ describe('Content Collections - render()', () => {
Content = mod.Content;
`,
- '/src/pages/index.astro': `
+ '/src/pages/index.astro': `
---
import { Content } from '../launch-week.ts';
---
@@ -246,15 +264,12 @@ describe('Content Collections - render()', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
await runInContainerWithContentListeners(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
diff --git a/packages/astro/test/units/dev/dev.test.js b/packages/astro/test/units/dev/dev.test.js
index c82232768..74f1d1e92 100644
--- a/packages/astro/test/units/dev/dev.test.js
+++ b/packages/astro/test/units/dev/dev.test.js
@@ -1,21 +1,12 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
-import {
- createFs,
- createRequestAndResponse,
- runInContainer,
- triggerFSEvent,
-} from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
describe('dev container', () => {
it('can render requests', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
---
const name = 'Testing';
---
@@ -26,11 +17,9 @@ describe('dev container', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
- await runInContainer({ fs, inlineConfig: { root: fileURLToPath(root) } }, async (container) => {
+ await runInContainer({ inlineConfig: { root: fixture.path } }, async (container) => {
const { req, res, text } = createRequestAndResponse({
method: 'GET',
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 () => {
- const fs = createFs(
- {
- '/src/components/test.astro': `<h1>{Astro.params.slug}</h1>`,
- '/src/pages/test-[slug].astro': `<h1>{Astro.params.slug}</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/components/test.astro': `<h1>{Astro.params.slug}</h1>`,
+ '/src/pages/test-[slug].astro': `<h1>{Astro.params.slug}</h1>`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
integrations: [
{
@@ -164,19 +80,15 @@ describe('dev container', () => {
});
it('Serves injected 404 route for any 404', async () => {
- const fs = createFs(
- {
- '/src/components/404.astro': `<h1>Custom 404</h1>`,
- '/src/pages/page.astro': `<h1>Regular page</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/components/404.astro': `<h1>Custom 404</h1>`,
+ '/src/pages/page.astro': `<h1>Regular page</h1>`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
integrations: [
{
@@ -226,10 +138,14 @@ describe('dev container', () => {
});
it('items in public/ are not available from root when using a base', async () => {
+ const fixture = await createFixture({
+ '/public/test.txt': `Test`,
+ });
+
await runInContainer(
{
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/sub/',
},
},
@@ -260,7 +176,11 @@ describe('dev container', () => {
});
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
let r = createRequestAndResponse({
method: 'GET',
diff --git a/packages/astro/test/units/dev/head-injection.test.js b/packages/astro/test/units/dev/head-injection.test.js
index 0796ba45f..fa61cea58 100644
--- a/packages/astro/test/units/dev/head-injection.test.js
+++ b/packages/astro/test/units/dev/head-injection.test.js
@@ -1,14 +1,13 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
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('head injection', () => {
it('Dynamic injection from component created in the page frontmatter', async () => {
- const fs = createFs(
+ const fixture = await createFixture(
{
'/src/components/Other.astro': `
<style>
@@ -64,9 +63,8 @@ describe('head injection', () => {
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
@@ -87,7 +85,7 @@ describe('head injection', () => {
});
it('Dynamic injection from a layout component', async () => {
- const fs = createFs(
+ const fixture = await createFixture(
{
'/src/components/Other.astro': `
<style>
@@ -164,9 +162,8 @@ describe('head injection', () => {
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
vite: { server: { middlewareMode: true } },
},
},
diff --git a/packages/astro/test/units/dev/hydration.test.js b/packages/astro/test/units/dev/hydration.test.js
index 369630f9a..03962a416 100644
--- a/packages/astro/test/units/dev/hydration.test.js
+++ b/packages/astro/test/units/dev/hydration.test.js
@@ -1,18 +1,14 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
-import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
describe('hydration', () => {
it(
'should not crash when reassigning a hydrated component',
{ skip: true, todo: "It seems that `components/Client.svelte` isn't found" },
async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
---
import Svelte from '../components/Client.svelte';
const Foo = Svelte;
@@ -26,15 +22,12 @@ describe('hydration', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
logLevel: 'silent',
},
},
diff --git a/packages/astro/test/units/dev/restart.test.js b/packages/astro/test/units/dev/restart.test.js
index 339b95fc1..9d5664cbf 100644
--- a/packages/astro/test/units/dev/restart.test.js
+++ b/packages/astro/test/units/dev/restart.test.js
@@ -1,25 +1,27 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
import {
createContainerWithAutomaticRestart,
startContainer,
} 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) {
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 () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
<html>
<head><title>Test</title></head>
<body>
@@ -27,16 +29,14 @@ describe('dev container restarts', () => {
</body>
</html>
`,
- '/astro.config.mjs': `
-
- `,
- },
- root,
- );
+ '/astro.config.mjs': ``,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
try {
@@ -52,40 +52,37 @@ describe('dev container restarts', () => {
// Create an error
let restartComplete = restart.restarted();
- fs.writeFileFromRootSync('/astro.config.mjs', 'const foo = bar');
-
- // Vite watches the real filesystem, so we have to mock this part. It's not so bad.
+ await fixture.writeFile('/astro.config.mjs', 'const foo = bar');
+ // TODO: fix this hack
restart.container.viteServer.watcher.emit(
'change',
- fs.getFullyResolvedPath('/astro.config.mjs'),
+ fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
);
// Wait for the restart to finish
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
restartComplete = restart.restarted();
- fs.writeFileFromRootSync('/astro.config.mjs', 'const foo = bar2');
-
- // Vite watches the real filesystem, so we have to mock this part. It's not so bad.
+ await fixture.writeFile('/astro.config.mjs', 'const foo = bar2');
+ // TODO: fix this hack
restart.container.viteServer.watcher.emit(
'change',
- fs.getFullyResolvedPath('/astro.config.mjs'),
+ fixture.getPath('/astro.config.mjs').replace(/\\/g, '/'),
);
hmrError = await restartComplete;
- assert.notEqual(typeof hmrError, 'undefined');
+ assert.ok(hmrError instanceof Error);
} finally {
await restart.container.close();
}
});
it('Restarts the container if previously started', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
<html>
<head><title>Test</title></head>
<body>
@@ -93,14 +90,14 @@ describe('dev container restarts', () => {
</body>
</html>
`,
- '/astro.config.mjs': ``,
- },
- root,
- );
+ '/astro.config.mjs': ``,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
await startContainer(restart.container);
assert.equal(isStarted(restart.container), true);
@@ -108,7 +105,12 @@ describe('dev container restarts', () => {
try {
// Trigger a change
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;
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 () => {
- const troot = new URL('../../fixtures/tailwindcss-ts/', import.meta.url);
- const fs = createFs(
- {
- '/src/pages/index.astro': ``,
- '/astro.config.ts': ``,
- },
- troot,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': ``,
+ '/astro.config.ts': ``,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
await startContainer(restart.container);
assert.equal(isStarted(restart.container), true);
@@ -137,7 +137,12 @@ describe('dev container restarts', () => {
try {
// Trigger a change
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;
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 () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': ``,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': ``,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
await startContainer(restart.container);
assert.equal(isStarted(restart.container), true);
try {
let restartComplete = restart.restarted();
- fs.writeFileSync('/package.json', `{}`);
- triggerFSEvent(restart.container, fs, '/package.json', 'change');
+ await fixture.writeFile('/package.json', `{}`);
+ // TODO: fix this hack
+ restart.container.viteServer.watcher.emit(
+ 'change',
+ fixture.getPath('/package.json').replace(/\\/g, '/'),
+ );
await restartComplete;
} finally {
await restart.container.close();
@@ -172,16 +180,15 @@ describe('dev container restarts', () => {
});
it('Is able to restart on viteServer.restart API call', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': ``,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': ``,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
await startContainer(restart.container);
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 () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': ``,
- '/.astro/settings.json': `{}`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': ``,
+ '/.astro/settings.json': `{}`,
+ });
const restart = await createContainerWithAutomaticRestart({
- fs,
- inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ inlineConfig: {
+ ...defaultInlineConfig,
+ root: fixture.path,
+ },
});
await startContainer(restart.container);
assert.equal(isStarted(restart.container), true);
try {
let restartComplete = restart.restarted();
- fs.mkdirSync('/.astro/', { recursive: true });
- fs.writeFileSync('/.astro/settings.json', `{ }`);
- triggerFSEvent(restart.container, fs, '/.astro/settings.json', 'change');
+ await fixture.writeFile('/.astro/settings.json', `{ }`);
+ // TODO: fix this hack
+ restart.container.viteServer.watcher.emit(
+ 'change',
+ fixture.getPath('/.astro/settings.json').replace(/\\/g, '/'),
+ );
await restartComplete;
} finally {
await restart.container.close();
diff --git a/packages/astro/test/units/render/chunk.test.js b/packages/astro/test/units/render/chunk.test.js
index b9c1c70f3..57ab74326 100644
--- a/packages/astro/test/units/render/chunk.test.js
+++ b/packages/astro/test/units/render/chunk.test.js
@@ -1,30 +1,23 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
-import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
describe('core/render chunk', () => {
it('does not throw on user object with type', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `\
---
const value = { type: 'foobar' }
---
<div id="chunk">{value}</div>
`,
- },
- root,
- );
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
logLevel: 'silent',
integrations: [],
},
diff --git a/packages/astro/test/units/render/components.test.js b/packages/astro/test/units/render/components.test.js
index b13d1fe88..991f0f105 100644
--- a/packages/astro/test/units/render/components.test.js
+++ b/packages/astro/test/units/render/components.test.js
@@ -1,16 +1,12 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
-import { createFs, createRequestAndResponse, runInContainer } from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js';
describe('core/render components', () => {
it('should sanitize dynamic tags', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
---
const TagA = 'p style=color:red;'
const TagB = 'p><script id="pwnd">console.log("pwnd")</script>'
@@ -23,15 +19,12 @@ describe('core/render components', () => {
</body>
</html>
`,
- },
- root,
- );
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
logLevel: 'silent',
integrations: [],
},
@@ -58,9 +51,8 @@ describe('core/render components', () => {
});
it('should merge `class` and `class:list`', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `
---
import Class from '../components/Class.astro';
import ClassList from '../components/ClassList.astro';
@@ -74,20 +66,17 @@ describe('core/render components', () => {
<BothFlipped 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/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/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)} />`,
- },
- root,
- );
+ '/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/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/BothSpread.astro': `<pre id="both-spread" set:html={JSON.stringify(Astro.props)} />`,
+ });
await runInContainer(
{
- fs,
inlineConfig: {
- root: fileURLToPath(root),
+ root: fixture.path,
logLevel: 'silent',
integrations: [],
},
diff --git a/packages/astro/test/units/routing/endpoints.test.js b/packages/astro/test/units/routing/endpoints.test.js
index 43d76af5a..8ce8cf1f5 100644
--- a/packages/astro/test/units/routing/endpoints.test.js
+++ b/packages/astro/test/units/routing/endpoints.test.js
@@ -1,16 +1,14 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/container.js';
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-const root = new URL('../../fixtures/api-routes/', import.meta.url);
const fileSystem = {
'/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 })`,
@@ -23,9 +21,9 @@ describe('endpoints', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
adapter: testAdapter(),
});
diff --git a/packages/astro/test/units/routing/manifest.test.js b/packages/astro/test/units/routing/manifest.test.js
index 523d86e6a..e95137728 100644
--- a/packages/astro/test/units/routing/manifest.test.js
+++ b/packages/astro/test/units/routing/manifest.test.js
@@ -1,11 +1,8 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { Logger } from '../../../dist/core/logger/core.js';
import { createRouteManifest } from '../../../dist/core/routing/manifest/create.js';
-import { createBasicSettings, createFs } from '../test-utils.js';
-
-const root = new URL('../../fixtures/alias/', import.meta.url);
+import { createBasicSettings, createFixture } from '../test-utils.js';
function getManifestRoutes(manifest) {
return manifest.routes.map((route) => ({
@@ -41,21 +38,17 @@ function assertRouteRelations(routes, relations) {
describe('routing - createRouteManifest', () => {
it('using trailingSlash: "never" does not match the index route when it contains a trailing slash', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/search',
trailingSlash: 'never',
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
const [{ pattern }] = manifest.routes;
assert.equal(pattern.test(''), true);
@@ -63,15 +56,12 @@ describe('routing - createRouteManifest', () => {
});
it('endpoint routes are sorted before page routes', async () => {
- const fs = createFs(
- {
- '/src/pages/[contact].astro': `<h1>test</h1>`,
- '/src/pages/[contact].ts': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/[contact].astro': `<h1>test</h1>`,
+ '/src/pages/[contact].ts': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/search',
trailingSlash: 'never',
experimental: {
@@ -91,9 +81,8 @@ describe('routing - createRouteManifest', () => {
];
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
@@ -117,18 +106,15 @@ describe('routing - createRouteManifest', () => {
});
it('static routes are sorted before dynamic and rest routes', async () => {
- const fs = createFs(
- {
- '/src/pages/[dynamic].astro': `<h1>test</h1>`,
- '/src/pages/[...rest].astro': `<h1>test</h1>`,
- '/src/pages/static.astro': `<h1>test</h1>`,
- '/src/pages/static-[dynamic].astro': `<h1>test</h1>`,
- '/src/pages/index.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/[dynamic].astro': `<h1>test</h1>`,
+ '/src/pages/[...rest].astro': `<h1>test</h1>`,
+ '/src/pages/static.astro': `<h1>test</h1>`,
+ '/src/pages/static-[dynamic].astro': `<h1>test</h1>`,
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/search',
trailingSlash: 'never',
experimental: {
@@ -137,9 +123,8 @@ describe('routing - createRouteManifest', () => {
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assertRouteRelations(getManifestRoutes(manifest), [
@@ -154,21 +139,18 @@ describe('routing - createRouteManifest', () => {
it('route sorting with multi-layer index page conflict', async () => {
// Reproducing regression from https://github.com/withastro/astro/issues/10071
- const fs = createFs(
- {
- '/src/pages/a/1.astro': `<h1>test</h1>`,
- '/src/pages/a/2.astro': `<h1>test</h1>`,
- '/src/pages/a/3.astro': `<h1>test</h1>`,
- '/src/pages/modules/[...slug].astro': `<h1>test</h1>`,
- '/src/pages/modules/index.astro': `<h1>test</h1>`,
- '/src/pages/test/[...slug].astro': `<h1>test</h1>`,
- '/src/pages/test/index.astro': `<h1>test</h1>`,
- '/src/pages/index.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/a/1.astro': `<h1>test</h1>`,
+ '/src/pages/a/2.astro': `<h1>test</h1>`,
+ '/src/pages/a/3.astro': `<h1>test</h1>`,
+ '/src/pages/modules/[...slug].astro': `<h1>test</h1>`,
+ '/src/pages/modules/index.astro': `<h1>test</h1>`,
+ '/src/pages/test/[...slug].astro': `<h1>test</h1>`,
+ '/src/pages/test/index.astro': `<h1>test</h1>`,
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/search',
trailingSlash: 'never',
experimental: {
@@ -177,9 +159,8 @@ describe('routing - createRouteManifest', () => {
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assertRouteRelations(getManifestRoutes(manifest), [
@@ -200,24 +181,21 @@ describe('routing - createRouteManifest', () => {
});
it('route sorting respects the file tree', async () => {
- const fs = createFs(
- {
- '/src/pages/[dynamic_folder]/static.astro': `<h1>test</h1>`,
- '/src/pages/[dynamic_folder]/index.astro': `<h1>test</h1>`,
- '/src/pages/[dynamic_folder]/[...rest].astro': `<h1>test</h1>`,
- '/src/pages/[...rest]/static.astro': `<h1>test</h1>`,
- '/src/pages/[...rest]/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
- '/src/pages/[dynamic_file].astro': `<h1>test</h1>`,
- '/src/pages/[...other].astro': `<h1>test</h1>`,
- '/src/pages/static.astro': `<h1>test</h1>`,
- '/src/pages/index.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/[dynamic_folder]/static.astro': `<h1>test</h1>`,
+ '/src/pages/[dynamic_folder]/index.astro': `<h1>test</h1>`,
+ '/src/pages/[dynamic_folder]/[...rest].astro': `<h1>test</h1>`,
+ '/src/pages/[...rest]/static.astro': `<h1>test</h1>`,
+ '/src/pages/[...rest]/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
+ '/src/pages/[dynamic_file].astro': `<h1>test</h1>`,
+ '/src/pages/[...other].astro': `<h1>test</h1>`,
+ '/src/pages/static.astro': `<h1>test</h1>`,
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
base: '/search',
trailingSlash: 'never',
experimental: {
@@ -226,9 +204,8 @@ describe('routing - createRouteManifest', () => {
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assertRouteRelations(getManifestRoutes(manifest), [
@@ -263,15 +240,12 @@ describe('routing - createRouteManifest', () => {
});
it('injected routes are sorted in legacy mode above filesystem routes', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -289,9 +263,8 @@ describe('routing - createRouteManifest', () => {
];
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
@@ -315,15 +288,12 @@ describe('routing - createRouteManifest', () => {
});
it('injected routes are sorted alongside filesystem routes', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/[...slug].astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -345,9 +315,8 @@ describe('routing - createRouteManifest', () => {
];
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
@@ -371,15 +340,12 @@ describe('routing - createRouteManifest', () => {
});
it('redirects are sorted in legacy mode below the filesystem routes', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/contributing.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/contributing.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -392,9 +358,8 @@ describe('routing - createRouteManifest', () => {
},
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
@@ -418,15 +383,12 @@ describe('routing - createRouteManifest', () => {
});
it('redirects are sorted alongside the filesystem routes', async () => {
- const fs = createFs(
- {
- '/src/pages/index.astro': `<h1>test</h1>`,
- '/src/pages/blog/contributing.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/index.astro': `<h1>test</h1>`,
+ '/src/pages/blog/contributing.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -445,9 +407,8 @@ describe('routing - createRouteManifest', () => {
},
});
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
@@ -471,14 +432,11 @@ describe('routing - createRouteManifest', () => {
});
it('report colliding static routes', async () => {
- const fs = createFs(
- {
- '/src/pages/contributing.astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/contributing.astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -496,9 +454,8 @@ describe('routing - createRouteManifest', () => {
];
const manifestOptions = {
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
};
const { logger, logs } = getLogger();
@@ -523,15 +480,12 @@ describe('routing - createRouteManifest', () => {
});
it('report colliding SSR dynamic routes', async () => {
- const fs = createFs(
- {
- '/src/pages/[foo].astro': `<h1>test</h1>`,
- '/src/pages/[bar].astro': `<h1>test</h1>`,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/[foo].astro': `<h1>test</h1>`,
+ '/src/pages/[bar].astro': `<h1>test</h1>`,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -542,9 +496,8 @@ describe('routing - createRouteManifest', () => {
});
const manifestOptions = {
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
};
const { logger, logs } = getLogger();
@@ -569,16 +522,13 @@ describe('routing - createRouteManifest', () => {
});
it('should concatenate each part of the segment. issues#10122', async () => {
- const fs = createFs(
- {
- '/src/pages/a-[b].astro': `<h1>test</h1>`,
- '/src/pages/blog/a-[b].233.ts': ``,
- },
- root,
- );
+ const fixture = await createFixture({
+ '/src/pages/a-[b].astro': `<h1>test</h1>`,
+ '/src/pages/blog/a-[b].233.ts': ``,
+ });
const settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
base: '/search',
trailingSlash: 'never',
@@ -599,9 +549,8 @@ describe('routing - createRouteManifest', () => {
];
const manifest = createRouteManifest({
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
});
assert.deepEqual(getManifestRoutes(manifest), [
diff --git a/packages/astro/test/units/routing/route-matching.test.js b/packages/astro/test/units/routing/route-matching.test.js
index a9a0e48a3..1ef383d55 100644
--- a/packages/astro/test/units/routing/route-matching.test.js
+++ b/packages/astro/test/units/routing/route-matching.test.js
@@ -11,12 +11,11 @@ import { createDevelopmentManifest } from '../../../dist/vite-plugin-astro-serve
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-const root = new URL('../../fixtures/alias/', import.meta.url);
const fileSystem = {
'/src/pages/[serverDynamic].astro': `
---
@@ -131,15 +130,14 @@ describe('Route matching', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
trailingSlash: 'never',
output: 'hybrid',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
@@ -149,9 +147,8 @@ describe('Route matching', () => {
pipeline = DevPipeline.create(undefined, { loader, logger: defaultLogger, manifest, settings });
manifestData = createRouteManifest(
{
- cwd: fileURLToPath(root),
+ cwd: fixture.path,
settings,
- fsMod: fs,
},
defaultLogger,
);
diff --git a/packages/astro/test/units/routing/route-sanitization.test.js b/packages/astro/test/units/routing/route-sanitization.test.js
index 802418868..7b6dcedf6 100644
--- a/packages/astro/test/units/routing/route-sanitization.test.js
+++ b/packages/astro/test/units/routing/route-sanitization.test.js
@@ -1,17 +1,15 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import * as cheerio from 'cheerio';
import { createContainer } from '../../../dist/core/dev/container.js';
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-const root = new URL('../../fixtures/alias/', import.meta.url);
const fileSystem = {
'/src/pages/[...testSlashTrim].astro': `
---
@@ -34,15 +32,14 @@ describe('Route sanitization', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
trailingSlash: 'never',
output: 'hybrid',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
diff --git a/packages/astro/test/units/routing/trailing-slash.test.js b/packages/astro/test/units/routing/trailing-slash.test.js
index a9e8fe945..d9ba53b38 100644
--- a/packages/astro/test/units/routing/trailing-slash.test.js
+++ b/packages/astro/test/units/routing/trailing-slash.test.js
@@ -1,16 +1,14 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/container.js';
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-const root = new URL('../../fixtures/api-routes/', import.meta.url);
const fileSystem = {
'/src/pages/api.ts': `export const GET = () => Response.json({ success: true })`,
};
@@ -20,15 +18,14 @@ describe('trailingSlash', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
trailingSlash: 'always',
output: 'server',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
diff --git a/packages/astro/test/units/runtime/endpoints.test.js b/packages/astro/test/units/runtime/endpoints.test.js
index 47f52a2df..313453c63 100644
--- a/packages/astro/test/units/runtime/endpoints.test.js
+++ b/packages/astro/test/units/runtime/endpoints.test.js
@@ -1,11 +1,10 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/container.js';
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
@@ -20,14 +19,13 @@ describe('endpoints', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem, root);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
diff --git a/packages/astro/test/units/teardown.js b/packages/astro/test/units/teardown.js
new file mode 100644
index 000000000..eeb718a37
--- /dev/null
+++ b/packages/astro/test/units/teardown.js
@@ -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;
+ }
+ }
+}
diff --git a/packages/astro/test/units/test-utils.js b/packages/astro/test/units/test-utils.js
index fea8e967e..9eb635cc9 100644
--- a/packages/astro/test/units/test-utils.js
+++ b/packages/astro/test/units/test-utils.js
@@ -1,8 +1,7 @@
import { EventEmitter } from 'node:events';
import realFS from 'node:fs';
-import npath from 'node:path';
import { fileURLToPath } from 'node:url';
-import { Volume } from 'memfs';
+import { createFixture as _createFixture } from 'fs-fixture';
import httpMocks from 'node-mocks-http';
import { getDefaultClientDirectives } from '../../dist/core/client-directive/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 { Pipeline } from '../../dist/core/render/index.js';
import { RouteCache } from '../../dist/core/render/route-cache.js';
-import { unixify } from './correct-path.js';
/** @type {import('../../src/core/logger/core').Logger} */
export const defaultLogger = new Logger({
@@ -27,102 +25,21 @@ export const silentLogging = {
level: 'error',
};
-class VirtualVolume extends Volume {
- #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);
-}
+const tempFixturesDir = fileURLToPath(new URL('./_temp-fixtures/', import.meta.url));
/**
- *
- * @param {import('../../src/core/dev/container').Container} container
- * @param {typeof import('node:fs')} fs
- * @param {string} shortPath
- * @param {'change'} eventType
+ * @param {import('fs-fixture').FileTree} tree
*/
-export function triggerFSEvent(container, fs, shortPath, eventType) {
- container.viteServer.watcher.emit(eventType, fs.getFullyResolvedPath(shortPath));
-
- if (!fileURLToPath(container.settings.config.root).startsWith('/')) {
- const drive = fileURLToPath(container.settings.config.root).slice(0, 2);
- container.viteServer.watcher.emit(eventType, drive + fs.getFullyResolvedPath(shortPath));
- }
+export async function createFixture(tree) {
+ return await _createFixture(
+ {
+ 'package.json': '{}',
+ ...tree,
+ },
+ {
+ tempDir: tempFixturesDir,
+ },
+ );
}
export function createRequestAndResponse(reqOptions = {}) {
diff --git a/packages/astro/test/units/vite-plugin-astro-server/request.test.js b/packages/astro/test/units/vite-plugin-astro-server/request.test.js
index 26f446cb1..b99a2cb60 100644
--- a/packages/astro/test/units/vite-plugin-astro-server/request.test.js
+++ b/packages/astro/test/units/vite-plugin-astro-server/request.test.js
@@ -1,6 +1,5 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/container.js';
import { createLoader } from '../../../dist/core/module-loader/index.js';
import { createRouteManifest } from '../../../dist/core/routing/index.js';
@@ -12,13 +11,13 @@ import testAdapter from '../../test-adapter.js';
import {
createAstroModule,
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-async function createDevPipeline(overrides = {}) {
- const settings = overrides.settings ?? (await createBasicSettings({ root: '/' }));
+async function createDevPipeline(overrides = {}, root) {
+ const settings = overrides.settings ?? (await createBasicSettings({ root }));
const loader = overrides.loader ?? createLoader();
const manifest = createDevelopmentManifest(settings);
@@ -28,31 +27,31 @@ async function createDevPipeline(overrides = {}) {
describe('vite-plugin-astro-server', () => {
describe('request', () => {
it('renders a request', async () => {
- 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);
- },
- }),
+ const fixture = await createFixture({
+ // Note that the content doesn't matter here because we are using a custom loader.
+ '/src/pages/index.astro': '',
});
- const controller = createController({ loader: pipeline.loader });
- const { req, res, text } = createRequestAndResponse();
- const fs = createFs(
+ const pipeline = await createDevPipeline(
{
- // Note that the content doesn't matter here because we are using a custom loader.
- '/src/pages/index.astro': '',
+ 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 { req, res, text } = createRequestAndResponse();
const manifestData = createRouteManifest(
{
- fsMod: fs,
+ cwd: fixture.path,
settings: pipeline.settings,
},
defaultLogger,
@@ -82,7 +81,6 @@ describe('vite-plugin-astro-server', () => {
let settings;
before(async () => {
- const root = new URL('../../fixtures/api-routes/', import.meta.url);
const fileSystem = {
'/src/pages/url.astro': `{Astro.request.url}`,
'/src/pages/prerendered.astro': `---
@@ -90,14 +88,13 @@ describe('vite-plugin-astro-server', () => {
---
{Astro.request.url}`,
};
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
diff --git a/packages/astro/test/units/vite-plugin-astro-server/response.test.js b/packages/astro/test/units/vite-plugin-astro-server/response.test.js
index fadaed99f..2d256fb71 100644
--- a/packages/astro/test/units/vite-plugin-astro-server/response.test.js
+++ b/packages/astro/test/units/vite-plugin-astro-server/response.test.js
@@ -1,16 +1,14 @@
import * as assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test';
-import { fileURLToPath } from 'node:url';
import { createContainer } from '../../../dist/core/dev/container.js';
import testAdapter from '../../test-adapter.js';
import {
createBasicSettings,
- createFs,
+ createFixture,
createRequestAndResponse,
defaultLogger,
} from '../test-utils.js';
-const root = new URL('../../fixtures/api-routes/', import.meta.url);
const fileSystem = {
'/src/pages/index.js': `export const GET = () => {
const headers = new Headers();
@@ -51,14 +49,13 @@ describe('endpoints', () => {
let settings;
before(async () => {
- const fs = createFs(fileSystem, root);
+ const fixture = await createFixture(fileSystem);
settings = await createBasicSettings({
- root: fileURLToPath(root),
+ root: fixture.path,
output: 'server',
adapter: testAdapter(),
});
container = await createContainer({
- fs,
settings,
logger: defaultLogger,
});
diff --git a/patches/fs-fixture@2.4.0.patch b/patches/fs-fixture@2.4.0.patch
new file mode 100644
index 000000000..1ec3a3c4d
--- /dev/null
+++ b/patches/fs-fixture@2.4.0.patch
@@ -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};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ad9ac3a17..78f2c5470 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4,6 +4,11 @@ settings:
autoInstallPeers: false
excludeLinksFromLockfile: false
+patchedDependencies:
+ fs-fixture@2.4.0:
+ hash: hvkuaks2ic76pdflr3iifgi4ku
+ path: patches/fs-fixture@2.4.0.patch
+
importers:
.:
@@ -703,15 +708,15 @@ importers:
expect-type:
specifier: ^1.1.0
version: 1.1.0
+ fs-fixture:
+ specifier: ^2.4.0
+ version: 2.4.0(patch_hash=hvkuaks2ic76pdflr3iifgi4ku)
mdast-util-mdx:
specifier: ^3.0.0
version: 3.0.0
mdast-util-mdx-jsx:
specifier: ^3.1.3
version: 3.1.3
- memfs:
- specifier: ^4.14.0
- version: 4.14.0
node-mocks-http:
specifier: ^1.16.1
version: 1.16.1(@types/node@18.19.50)
@@ -2665,12 +2670,6 @@ importers:
specifier: workspace:*
version: link:../../..
- packages/astro/test/fixtures/content-mixed-errors:
- dependencies:
- astro:
- specifier: workspace:*
- version: link:../../..
-
packages/astro/test/fixtures/content-ssr-integration:
dependencies:
'@astrojs/mdx':
@@ -4172,6 +4171,15 @@ importers:
specifier: workspace:*
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:
dependencies:
'@astrojs/cli-kit':
@@ -6528,24 +6536,6 @@ packages:
resolution: {integrity: sha512-n5JEf16Wr4mdkRMZ8wMP/wN9/sHmTjRPbouXjJH371mZ2LEGDl72t8tEsMRNFerQN/QJtivOxqK1frdGa4QK5Q==}
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':
resolution: {integrity: sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q==}
@@ -8274,6 +8264,10 @@ packages:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
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:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -8475,10 +8469,6 @@ packages:
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
engines: {node: '>=16.17.0'}
- hyperdyperid@1.2.0:
- resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==}
- engines: {node: '>=10.18'}
-
hyperid@3.3.0:
resolution: {integrity: sha512-7qhCVT4MJIoEsNcbhglhdmBKb09QtcmJNiIQGq7js/Khf5FtQQ9bzcAuloeqBeee7XD7JqDeve9KNlQya5tSGQ==}
@@ -8924,10 +8914,6 @@ packages:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
- memfs@4.14.0:
- resolution: {integrity: sha512-JUeY0F/fQZgIod31Ja1eJgiSxLn7BfQlCnqhwXFBzFHEw63OdLK7VJUJ7bnzNsWgCyoUP5tEp1VRY8rDaYzqOA==}
- engines: {node: '>= 4.0.0'}
-
merge-anything@5.1.7:
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
engines: {node: '>=12.13'}
@@ -10243,12 +10229,6 @@ packages:
thenify@3.3.1:
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:
resolution: {integrity: sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA==}
engines: {node: '>=8'}
@@ -10302,12 +10282,6 @@ packages:
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
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:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
@@ -11997,22 +11971,6 @@ snapshots:
'@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':
dependencies:
'@libsql/core': 0.14.0
@@ -13833,6 +13791,8 @@ snapshots:
jsonfile: 4.0.0
universalify: 0.1.2
+ fs-fixture@2.4.0(patch_hash=hvkuaks2ic76pdflr3iifgi4ku): {}
+
fsevents@2.3.2:
optional: true
@@ -14145,8 +14105,6 @@ snapshots:
human-signals@5.0.0: {}
- hyperdyperid@1.2.0: {}
-
hyperid@3.3.0:
dependencies:
buffer: 5.7.1
@@ -14709,13 +14667,6 @@ snapshots:
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:
dependencies:
is-what: 4.1.16
@@ -16344,10 +16295,6 @@ snapshots:
dependencies:
any-promise: 1.3.0
- thingies@1.21.0(tslib@2.7.0):
- dependencies:
- tslib: 2.7.0
-
timestring@6.0.0: {}
tinybench@2.9.0: {}
@@ -16387,10 +16334,6 @@ snapshots:
dependencies:
punycode: 2.3.1
- tree-dump@1.0.2(tslib@2.7.0):
- dependencies:
- tslib: 2.7.0
-
trim-lines@3.0.1: {}
trough@2.2.0: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index be78c826e..22dae231e 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,9 +1,11 @@
packages:
- 'packages/**/*'
+ - 'packages/astro/test/units/_temp-fixtures'
- 'examples/**/*'
- 'smoke/**/*'
- 'scripts'
- 'benchmark'
- 'benchmark/packages/*'
# Below excludes are only for Turbo because it doesn't respect gitignore like pnpm does
+ - '!packages/astro/test/units/_temp-fixtures/*'
- '!**/.vercel/**'
diff --git a/scripts/cmd/test.js b/scripts/cmd/test.js
index 3182c4b90..3b266ff1c 100644
--- a/scripts/cmd/test.js
+++ b/scripts/cmd/test.js
@@ -25,6 +25,8 @@ export default async function test() {
timeout: { type: 'string', alias: 't' },
// Test setup file
setup: { type: 'string', alias: 's' },
+ // Test teardown file
+ teardown: { type: 'string' },
},
});
@@ -59,6 +61,10 @@ export default async function test() {
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
run({
files,
@@ -74,6 +80,10 @@ export default async function test() {
// so we set it here manually
process.exitCode = 1;
})
+ .on('end', () => {
+ const testPassed = process.exitCode === 0 || process.exitCode === undefined;
+ teardownModule?.default(testPassed);
+ })
.pipe(new spec())
.pipe(process.stdout);
}